admin
2021-09-24 f788607ff771a47bc60d6a86e00b3433c40f3d2c
src/main/java/com/yeshi/buwan/service/imp/SearchService.java
@@ -1,35 +1,43 @@
package com.yeshi.buwan.service.imp;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.*;
import javax.annotation.Resource;
import com.yeshi.buwan.dao.video.AlbumVideoMapDao;
import com.yeshi.buwan.dao.*;
import com.yeshi.buwan.dao.system.DetailSystemDao;
import com.yeshi.buwan.domain.*;
import com.yeshi.buwan.domain.video.AlbumVideoMap;
import com.yeshi.buwan.service.manager.SolrAlbumDataManager;
import com.yeshi.buwan.domain.solr.SolrAlbumVideo;
import com.yeshi.buwan.domain.system.DetailSystem;
import com.yeshi.buwan.domain.video.InternetSearchVideo;
import com.yeshi.buwan.domain.web.DetailSystemSelect;
import com.yeshi.buwan.domain.web.HotSearchAdmin;
import com.yeshi.buwan.dto.search.SolrResultDTO;
import com.yeshi.buwan.dto.search.SolrVideoSearchFilter;
import com.yeshi.buwan.videos.pptv.PPTVUtil;
import com.yeshi.buwan.service.inter.video.VideoInfoExtraService;
import com.yeshi.buwan.service.manager.search.SolrAlbumVideoDataManager;
import com.yeshi.buwan.service.manager.search.SolrInternetSearchVideoDataManager;
import com.yeshi.buwan.util.*;
import com.yeshi.buwan.util.factory.VideoInfoFactory;
import com.yeshi.buwan.util.video.VideoConstant;
import com.yeshi.buwan.vo.video.VideoListResultVO;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.orm.hibernate4.HibernateCallback;
import org.springframework.stereotype.Service;
import com.yeshi.buwan.dao.DetailSystemDao;
import com.yeshi.buwan.dao.HotSearchDao;
import com.yeshi.buwan.dao.SearchDao;
import com.yeshi.buwan.dao.SuperHotSearchDao;
import com.yeshi.buwan.dao.VideoBanQuanVideoDao;
import com.yeshi.buwan.dao.VideoInfoDao;
import com.yeshi.buwan.domain.web.DetailSystemSelect;
import com.yeshi.buwan.domain.web.HotSearchAdmin;
import javax.annotation.Resource;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.*;
@Service
public class SearchService {
    private Logger logger = LoggerFactory.getLogger(SearchService.class);
    private final String ALBUM_SEARCH_FUZZY_KEYS = "《,》,。";
    @Resource
    private SearchDao searchDao;
    @Resource
@@ -41,22 +49,23 @@
    @Resource
    private SuperHotSearchDao superHotSearchDao;
    @Resource
    private ConfigService configService;
    @Resource
    private VideoBanQuanVideoDao videoBanQuanVideoDao;
    @Resource
    private DetailSystemDao detailSystemDao;
    @Resource
    private AlbumVideoMapDao albumVideoMapDao;
    private SolrAlbumVideoDataManager solrAlbumDataManager;
    @Resource
    private SolrAlbumDataManager solrAlbumDataManager;
    private SolrInternetSearchVideoDataManager solrInternetSearchVideoDataManager;
    @Resource
    private VideoInfoExtraService videoInfoExtraService;
    @SuppressWarnings("rawtypes")
    @Cacheable(value = "userCache", key = "'suggestSearch'+'-'+#key+'-'+#system")
    public List<String> suggestSearch(String key, String system) {
        if (StringUtil.isNullOrEmpty(key) || key.startsWith("%"))
            return new ArrayList<String>();
            return new ArrayList<>();
        List<String> list;
        Session session = null;
@@ -67,7 +76,7 @@
            sql = "select name as result from wk_video_video where name like ?";
        }
        list = new ArrayList<String>();
        list = new ArrayList<>();
        List li = null;
        try {
@@ -93,7 +102,7 @@
        }
        Iterator<String> it = set.iterator();
        list = new ArrayList<String>();
        list = new ArrayList<>();
        while (it.hasNext()) {
            list.add(it.next());
            if (list.size() > 10)
@@ -135,7 +144,7 @@
                    .append(") order by REPLACE(v.name,?,'') ,v.watchCount desc").toString();
        else
            sql = "from VideoInfo v where v.show='1' and (v.name like ?) order by REPLACE(v.name,?,''),v.watchCount desc";// 改为sql
        List<Serializable> list = new ArrayList<Serializable>();
        List<Serializable> list = new ArrayList<>();
        BaiduVideoUtil util = new BaiduVideoUtil();
        List<VideoInfo> localList = videoInfoDao.list(sql, (page - 1) * Constant.pageCount, Constant.pageCount,
                new String[]{(new StringBuilder("")).append(key).append("%").toString(), key});
@@ -196,7 +205,7 @@
        searchDao.create(sh);
        // 查询数据库
        List<VideoInfo> list = new ArrayList<VideoInfo>();
        List<VideoInfo> list = new ArrayList<>();
        List<VideoInfo> localList = null;
        try {
            long startt = System.currentTimeMillis();
@@ -220,7 +229,7 @@
                sql = sql.substring(0, sql.length() - 9);
            List rlist = videoInfoDao.sqlList(sql);
            List<Integer> pList = new ArrayList<Integer>();
            List<Integer> pList = new ArrayList<>();
            for (int i = 0; i < localList.size(); i++) {
                if (Integer.parseInt(rlist.get(i) + "") < 1) {
                    pList.add(i);
@@ -249,9 +258,142 @@
    }
    @Cacheable(value = "userCache", key = "'searchNew'+'-'+#detailSystem+'-'+#key+'-'+#page+'-'+#videoType+'-'+#system+'-'+#cacheMD5")
    public List<VideoInfo> searchNew(String detailSystem, String ip, String uid, String key, int page, int videoType,
                                     String system, List<Long> resourceList, String cacheMD5) {
    private VideoInfo loadAlbumData(VideoInfo video) {
        video.setShowType(1);
        if (!StringUtil.isNullOrEmpty(video.getMainActor())) {
            video.setMainActor("主演:" + video.getMainActor());
        }
        //设置tag
        String tag = "";
        if (!StringUtil.isNullOrEmpty(video.getYear())) {
            tag += video.getYear() + "/";
        }
        if (video.getVideoType() != null) {
            String vt = VideoConstant.getMainCategoryName(video.getVideoType().getId());
            if (!StringUtil.isNullOrEmpty(vt)) {
                tag += vt + "/";
            }
        }
        if (!StringUtil.isNullOrEmpty(video.getArea())) {
            tag += video.getArea() + "/";
        }
        if (tag.endsWith("/"))
            tag = tag.substring(0, tag.length() - 1);
        video.setTag(tag);
        return video;
    }
    public SearchResult searchAlbum(int videoType, String key, List<Long> resourceIds, int page, int pageSize, boolean fuzzy) {
        List<VideoInfo> localList = new ArrayList<>();
        //专辑视频集合
        Set<String> solrAlbumVids = new HashSet<>();
        SolrVideoSearchFilter filter = new SolrVideoSearchFilter();
        filter.setFuzzy(fuzzy);
        filter.setKey(key);
        if (videoType == Constant.SEARCH_RESULT_TYPE_HIGH_DEFINITION) {
            filter.setResourceIds(Arrays.asList(new String[]{PPTVUtil.RESOURCE_ID + ""}));
            logger.info("高清搜索# key:{}", key);
        } else {
            List<String> rids = new ArrayList<>();
            for (Long rid : resourceIds) {
                rids.add(rid + "");
            }
            filter.setResourceIds(rids);
            filter.setVideoType(videoType == 0 ? null : videoType);
        }
        filter.setContentType(1);
        SolrResultDTO solrResultDTO = solrAlbumDataManager.find(filter, page, pageSize);
        Set<String> albumSet = new HashSet<>();
        int albumCount = 0;
        if (solrResultDTO != null) {
            albumCount = solrResultDTO.getTotalCount();
            for (SolrAlbumVideo sv : (List<SolrAlbumVideo>) solrResultDTO.getVideoList()) {
                VideoInfo video = VideoInfoFactory.create(sv);
                albumSet.add(video.getName() + "#" + video.getVideoType().getId() + "#" + video.getYear());
                video = loadAlbumData(video);
                localList.add(video);
                solrAlbumVids.add(video.getId());
            }
        }
        //第一页,不为高清时搜索
        if (page == 1 && videoType != Constant.SEARCH_RESULT_TYPE_HIGH_DEFINITION) {
            //page为1时 全网搜
            SolrResultDTO internetSearchResultDTO = solrInternetSearchVideoDataManager.find(filter, 1, 20);
            if (internetSearchResultDTO != null && internetSearchResultDTO.getVideoList().size() > 0) {
                List<InternetSearchVideo> iList = internetSearchResultDTO.getVideoList();
                List<InternetSearchVideo> isvList = new ArrayList<>();
                if (iList != null && iList.size() > 0)
                    isvList.addAll(iList);
                //删除前面有的数据,根据rootType与名称筛选
                for (int i = 0; i < isvList.size(); i++) {
                    String uniqueId = isvList.get(i).getName() + "#" + isvList.get(i).getRootType() + "#" + isvList.get(i).getYear();
                    if (albumSet.contains(uniqueId)) {
                        isvList.remove(i);
                        i--;
                    }
                }
                //精确匹配,不分词
                if (!fuzzy) {
                    for (InternetSearchVideo sv : isvList) {
                        VideoInfo video = VideoInfoFactory.create(sv);
                        video = loadAlbumData(video);
                        //第一个专辑数量
                        if (albumCount < 3) {
                            localList.add(video);
                        } else {
                            if (video.getName().equalsIgnoreCase(key))
                                localList.add(video);
                        }
                    }
                } else {
                    for (InternetSearchVideo sv : isvList) {
                        VideoInfo video = VideoInfoFactory.create(sv);
                        video = loadAlbumData(video);
                        localList.add(video);
                    }
                }
            }
            //按关键词的匹配度排序
            Comparator<VideoInfo> cm = (VideoInfo o1, VideoInfo o2) -> {
                if (o1.getDefinition() - o2.getDefinition() == 0) {
                    float s1 = CompareStrSimUtil.getSimilarityRatio(o1.getName(), key, true);
                    float s2 = CompareStrSimUtil.getSimilarityRatio(o2.getName(), key, true);
//                        if (s1 != s2)//相似度越高越靠前
                    try {
                        return s1 != s2 ? (s2 > s1 ? 1 : -1) : (Integer.parseInt(o2.getYear()) - Integer.parseInt(o1.getYear()));
                    } catch (Exception e) {
                        return s2 > s1 ? 1 : -1;
                    }
//                        else
//                            return o1.getDefinition() - o2.getDefinition();//高清排在前
                } else {
                    return o2.getDefinition() - o1.getDefinition();//高清排在前
                }
            };
            Collections.sort(localList, cm);
        }
        //未搜索到内容
        if (localList == null || localList.size() == 0) {
            logger.warn("专辑搜索无结果#{}", key);
        }
        return new SearchResult(albumCount, localList);
    }
    private void filterSearchResult(List<VideoInfo> localList, List<Long> resourceList) {
        String sql = "";
        String resourceWhere = "";
        for (Long re : resourceList) {
            resourceWhere += " rv.resourceid=" + re + " or";
@@ -260,20 +402,58 @@
        if (resourceWhere.endsWith("or"))
            resourceWhere = resourceWhere.substring(0, resourceWhere.length() - 2);
        List<String> filterVideoIdList = new ArrayList<>();
        for (int i = 0; i < localList.size(); i++) {
            if (NumberUtil.isNumeric(localList.get(i).getId())) {
                filterVideoIdList.add(localList.get(i).getId());
                sql += " select count(*) from wk_resource_video rv left join wk_video_video v on rv.videoid=v.id where v.id is not null and v.show=1 and rv.videoid="
                        + localList.get(i).getId() + " and (" + resourceWhere + ") union all";
            }
        }
        if (sql.endsWith("union all"))
            sql = sql.substring(0, sql.length() - 9);
        List rlist = StringUtil.isNullOrEmpty(sql) ? new ArrayList() : videoInfoDao.sqlList(sql);
        Set<String> deleteVids = new HashSet<>();
        for (int i = 0; i < filterVideoIdList.size(); i++) {
            if (Integer.parseInt(rlist.get(i) + "") < 1) {
                deleteVids.add(filterVideoIdList.get(i));
            }
        }
        for (int i = 0; i < localList.size(); i++) {
            if (deleteVids.contains(localList.get(i).getId())) {
                localList.remove(i);
                i--;
            }
        }
    }
    @Cacheable(value = "userCache", key = "'searchNew'+'-'+#detailSystem+'-'+#key+'-'+#page+'-'+#videoType+'-'+#system+'-'+#cacheMD5")
    public VideoListResultVO searchNew(String detailSystem, String ip, String uid, String key, int page, int videoType,
                                       String system, List<Long> resourceList, String cacheMD5) {
        SearchHistory sh = new SearchHistory();
        sh.setCreatetime((new StringBuilder(String.valueOf(System.currentTimeMillis()))).toString());
        sh.setIp(ip);
        if (!StringUtil.isNullOrEmpty(key) && key.length() > 30)
            key = key.substring(0, 30);
        sh.setKey(key);
        UserInfo user = new UserInfo();
        user.setId(uid);
        sh.setUser(user);
        if (uid != null) {
            UserInfo user = new UserInfo();
            user.setId(uid);
            sh.setUser(user);
        }
        searchDao.create(sh);
        // 查询数据库
        List<VideoInfo> list = new ArrayList<VideoInfo>();
        //专辑数量
        long albumCount = 0L;
        List<VideoInfo> list = new ArrayList<>();
        List<VideoInfo> localList = null;
        try {
            long startt = System.currentTimeMillis();
@@ -281,89 +461,52 @@
            localList = new ArrayList<>();
            //先搜索专辑
            List<SolrVideo> solrVideoList = solrAlbumDataManager.findByKey(key, 1, videoType == 0 ? null : videoType, page);
            Set<String> solrAlbumVids = new HashSet<>();
            for (SolrVideo sv : solrVideoList) {
                VideoInfo video = VideoInfoFactory.create(sv);
                video.setShowType(1);
                if (!StringUtil.isNullOrEmpty(video.getMainActor())) {
                    video.setMainActor("主演:" + video.getMainActor());
                }
            int pageSize = 20;
            SearchResult searchResult = searchAlbum(videoType, key, resourceList, page, pageSize, false);
                //设置tag
                String tag = "";
                if (!StringUtil.isNullOrEmpty(sv.getYear())) {
                    tag += sv.getYear() + "/";
                }
                if (video.getVideoType() != null) {
                    String vt = VideoConstant.getMainCategoryName(sv.getRootVideoType());
                    if (!StringUtil.isNullOrEmpty(vt)) {
                        tag += vt + "/";
                    }
                }
                if (!StringUtil.isNullOrEmpty(video.getArea())) {
                    tag += video.getArea() + "/";
                }
                if (tag.endsWith("/"))
                    tag = tag.substring(0, tag.length() - 1);
                video.setTag(tag);
                localList.add(video);
                solrAlbumVids.add(video.getId());
            if (page == 1 && (searchResult == null || searchResult.videoInfoList == null || searchResult.videoInfoList.size() == 0)) {
                searchResult = searchAlbum(videoType, key, resourceList, page, pageSize, true);
            }
            if (videoType == 0) {
            if (searchResult != null && searchResult.videoInfoList != null) {
                localList.addAll(searchResult.videoInfoList);
            }
            Set<String> solrAlbumVids = new HashSet<>();
            for (VideoInfo videoInfo : localList) {
                solrAlbumVids.add(videoInfo.getId());
            }
            int commonSolrPage = page - searchResult.getTotalCount() / pageSize;
            if (videoType == 0 && commonSolrPage > 0) {
                //搜索原始的
                List<VideoInfo> solrList = SolrUtil.search(key, page);
                for (VideoInfo vi : solrList) {
                    if (!solrAlbumVids.contains(vi.getId())) {
                        localList.add(vi);
                try {
                    List<VideoInfo> solrList = SolrUtil.search(key, commonSolrPage);
                    for (VideoInfo vi : solrList) {
                        if (!solrAlbumVids.contains(vi.getId())) {
                            localList.add(vi);
                        }
                    }
                } catch (Exception e) {
                }
            }
            System.out.println("搜索耗时:" + (System.currentTimeMillis() - startt));
            String sql = "";
            startt = System.currentTimeMillis();
            for (int i = 0; i < localList.size(); i++) {
                sql += " select count(*) from wk_resource_video rv left join wk_video_video v on rv.videoid=v.id where v.id is not null and v.show=1 and rv.videoid="
                        + localList.get(i).getId() + " and (" + resourceWhere + ") union all";
            }
            if (sql.endsWith("union all"))
                sql = sql.substring(0, sql.length() - 9);
            List rlist = videoInfoDao.sqlList(sql);
            List<Integer> pList = new ArrayList<Integer>();
            for (int i = 0; i < localList.size(); i++) {
                if (Integer.parseInt(rlist.get(i) + "") < 1) {
                    pList.add(i);
                    // localList.remove(i);
                    // i--;
                }
            }
            Collections.sort(pList);
            for (int i = pList.size() - 1; i >= 0; i--) {
                localList.remove((int) pList.get(i));
            }
            System.out.println("排除耗时:" + (System.currentTimeMillis() - startt));
            filterSearchResult(localList, resourceList);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
        if (localList != null && localList.size() > 0) {
            for (VideoInfo info : localList) {
                list.add(info);
            }
            list.addAll(localList);
        }
        return list;
        //获取附加信息
        list = videoInfoExtraService.batchExtra(list, resourceList);
        return new VideoListResultVO(list, videoType == 0 ? albumCount : 1000L);
    }
    public long searchCount(String key, String system) {
@@ -382,7 +525,7 @@
    @SuppressWarnings({"rawtypes"})
    @Cacheable(value = "userCache", key = "'getHotSearchList'+'-'+#system")
    public List<String> getHotSearchList(String system) {
        List<String> list = new ArrayList<String>();
        List<String> list = new ArrayList<>();
        try {
            List li = searchDao.sqlList(
                    "SELECT h.`name` FROM wk_video_super_hotsearch sh LEFT JOIN wk_video_hotsearch h ON sh.`hotsearchid`=h.`id`  WHERE sh.`detailsystem`=? ORDER BY h.`orderby` DESC",
@@ -455,16 +598,16 @@
    }
    @SuppressWarnings("unchecked")
    public List<HotSearchAdmin> getHotSearchAdmin(String key, int detailSystem, int page) {
        List<HotSearchAdmin> zhiBoClassList = new ArrayList<HotSearchAdmin>();
    public List<HotSearchAdmin> getHotSearchAdmin(String key, String systemId, int detailSystem, int page) {
        List<HotSearchAdmin> zhiBoClassList = new ArrayList<>();
        try {
            List<DetailSystem> detailSystemList = detailSystemDao.list("from DetailSystem");
            List<DetailSystem> detailSystemList = detailSystemDao.list("from DetailSystem ds where ds.system.id=" + systemId);
            String sql = "";
            if (detailSystem > 0)
                sql = "select sh.hotSearch from SuperHotSearch sh where sh.hotSearch.name like ? and sh.detailSystem.id="
                        + detailSystem + " order by  sh.createtime desc";
            else
                sql = "from HotSearch zb where zb.name like ? order by zb.createtime desc";
                sql = "from HotSearch zb where zb.name like ? and zb.system.id=" + systemId + " order by zb.createtime desc";
            List<HotSearch> list = hotSearchDao.list(sql, (page - 1) * Constant.pageCount, Constant.pageCount,
                    new Serializable[]{"%" + key + "%"});
@@ -472,7 +615,7 @@
                List<DetailSystem> detailSystemS = detailSystemDao
                        .list("select vb.detailSystem from SuperHotSearch vb where vb.hotSearch.id=" + vb.getId());
                List<DetailSystemSelect> dssList = new ArrayList<DetailSystemSelect>();
                List<DetailSystemSelect> dssList = new ArrayList<>();
                for (DetailSystem ds : detailSystemList) {
                    DetailSystemSelect dss = new DetailSystemSelect();
@@ -502,13 +645,13 @@
        return zhiBoClassList;
    }
    public long getHotSearchAdminCount(String key, int detailSystem) {
    public long getHotSearchAdminCount(String key, String systemId, int detailSystem) {
        String sql = "";
        if (detailSystem > 0)
            sql = "select count(*) from  (select count(*) from wk_video_super_hotsearch zb left join wk_video_hotsearch c on c.id=zb.hotsearchid where zb.detailsystem="
                    + detailSystem + " and c.name like '%" + key + "%' group by zb.hotsearchid) s";
        else
            sql = "select count(*) from wk_video_hotsearch h where h.name like '%" + key + "%'";
            sql = "select count(*) from wk_video_hotsearch h where h.name like '%" + key + "%' and h.system=" + systemId;
        return videoBanQuanVideoDao.getCountSQL(sql);
    }
@@ -602,4 +745,50 @@
    }
    /**
     * 将搜索结果对象转为视频对象
     *
     * @param solrAlbumVideoList
     * @param resourceList
     * @return
     */
    public List<VideoInfo> convertSolrAlbumResultToVideo(List<SolrAlbumVideo> solrAlbumVideoList, List<Long> resourceList) {
        List<VideoInfo> videoInfoList = new ArrayList<>();
        for (SolrAlbumVideo sv : solrAlbumVideoList) {
            VideoInfo video = VideoInfoFactory.create(sv);
            videoInfoList.add(video);
        }
        //获取附加信息
        videoInfoList = videoInfoExtraService.batchExtra(videoInfoList, resourceList);
        return videoInfoList;
    }
    public static class SearchResult {
        private int totalCount;
        private List<VideoInfo> videoInfoList;
        public SearchResult(int totalCount, List<VideoInfo> videoInfoList) {
            this.totalCount = totalCount;
            this.videoInfoList = videoInfoList;
        }
        public int getTotalCount() {
            return totalCount;
        }
        public void setTotalCount(int totalCount) {
            this.totalCount = totalCount;
        }
        public List<VideoInfo> getVideoInfoList() {
            return videoInfoList;
        }
        public void setVideoInfoList(List<VideoInfo> videoInfoList) {
            this.videoInfoList = videoInfoList;
        }
    }
}