package com.yeshi.buwan.service.imp; import com.yeshi.buwan.dao.*; import com.yeshi.buwan.dao.system.DetailSystemDao; import com.yeshi.buwan.domain.*; 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 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 private ClassService classService; @Resource private VideoInfoDao videoInfoDao; @Resource private HotSearchDao hotSearchDao; @Resource private SuperHotSearchDao superHotSearchDao; @Resource private VideoBanQuanVideoDao videoBanQuanVideoDao; @Resource private DetailSystemDao detailSystemDao; @Resource private SolrAlbumVideoDataManager solrAlbumDataManager; @Resource private SolrInternetSearchVideoDataManager solrInternetSearchVideoDataManager; @Resource private VideoInfoExtraService videoInfoExtraService; @SuppressWarnings("rawtypes") @Cacheable(value = "userCache", key = "'suggestSearch'+'-'+#key+'-'+#system") public List suggestSearch(String key, String system) { if (StringUtil.isNullOrEmpty(key) || key.startsWith("%")) return new ArrayList<>(); List list; Session session = null; if (key != null && key.length() > 10) key = key.substring(0, 10); String sql = ""; if (system.equalsIgnoreCase("1")) { sql = "select name as result from wk_video_video where name like ?"; } list = new ArrayList<>(); List li = null; try { li = videoInfoDao.sqlList(sql, new String[]{(new StringBuilder(String.valueOf(key))).append("%").toString()}); } catch (Exception e) { } if (li != null) { for (int i = 0; i < li.size(); i++) { Object objs = (Object) li.get(i); list.add(objs.toString()); } } Set set = new TreeSet(); if (list != null) { String st; for (Iterator iterator = list.iterator(); iterator.hasNext(); set.add(st)) st = (String) iterator.next(); } Iterator it = set.iterator(); list = new ArrayList<>(); while (it.hasNext()) { list.add(it.next()); if (list.size() > 10) break; } return list; } @SuppressWarnings("unchecked") public List search(String ip, String uid, String key, int page, int type, int videoType, String system) { SearchHistory sh = new SearchHistory(); sh.setCreatetime((new StringBuilder(String.valueOf(System.currentTimeMillis()))).toString()); sh.setIp(ip); sh.setKey(key); UserInfo user = new UserInfo(); user.setId(uid); sh.setUser(user); searchDao.create(sh); // 查询数据库 String videoTypeList[] = classService.getChildrenType(videoType); String typewhere = ""; if (system.equalsIgnoreCase("2")) { typewhere = " v.videoType.id=105 or v.videoType.id=106 or v.videoType.id=107 or v.videoType.id=108 "; } else if (videoType > 0) { for (int i = 0; i < videoTypeList.length; i++) typewhere = (new StringBuilder(String.valueOf(typewhere))).append(" or v.videoType.id=") .append(videoTypeList[i]).toString(); if (typewhere.startsWith(" or")) typewhere = typewhere.substring(3, typewhere.length()); } String sql; if (!StringUtil.isNullOrEmpty(typewhere))// 改为sql sql = (new StringBuilder("from VideoInfo v where v.show='1' and (v.name like ?) and (")).append(typewhere) .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 list = new ArrayList<>(); BaiduVideoUtil util = new BaiduVideoUtil(); List localList = videoInfoDao.list(sql, (page - 1) * Constant.pageCount, Constant.pageCount, new String[]{(new StringBuilder("")).append(key).append("%").toString(), key}); if (localList != null && localList.size() > 0) { for (VideoInfo info : localList) { list.add(info); } } // 查询数据库结束 if (system.equalsIgnoreCase("1")) if (page == 1) try { List fromNet = util.searchVideo(key); if (fromNet != null && fromNet.size() > 0) { for (int i = 0; i < fromNet.size(); i++) if (videoType == 0) list.add((VideoInfo) fromNet.get(i)); else if (((VideoInfo) fromNet.get(i)).getVideoType().getId() == (long) videoType) list.add((VideoInfo) fromNet.get(i)); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } final List newList = list; list = (List) searchDao.excute(new HibernateCallback>() { public List doInHibernate(Session session) throws HibernateException { return BanQuanUtil.filterShowVideo(newList, session); } }); return list; } @Cacheable(value = "userCache", key = "'search'+'-'+#detailSystem+'-'+#key+'-'+#page+'-'+#contentType+'-'+#system+'-'+#cacheMD5") public List search(String detailSystem, String ip, String uid, String key, int page, int contentType, String system, List resourceList, String cacheMD5) { String resourceWhere = ""; for (Long re : resourceList) { resourceWhere += " rv.resourceid=" + re + " or"; } if (resourceWhere.endsWith("or")) resourceWhere = resourceWhere.substring(0, resourceWhere.length() - 2); 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); searchDao.create(sh); // 查询数据库 List list = new ArrayList<>(); List localList = null; try { long startt = System.currentTimeMillis(); localList = null; if (contentType == 0) localList = SolrUtil.search(key, page); else if (contentType == 1) localList = SolrUtil.searchZhengPian(key, page); else localList = SolrUtil.searchZhuanJi(key, page); 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 pList = new ArrayList<>(); 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)); } catch (Exception e) { e.printStackTrace(); } finally { } if (localList != null && localList.size() > 0) { for (VideoInfo info : localList) { list.add(info); } } return list; } 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 resourceIds, int page, int pageSize, boolean fuzzy) { List localList = new ArrayList<>(); //专辑视频集合 Set 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 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 albumSet = new HashSet<>(); int albumCount = 0; if (solrResultDTO != null) { albumCount = solrResultDTO.getTotalCount(); for (SolrAlbumVideo sv : (List) 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 iList = internetSearchResultDTO.getVideoList(); List 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 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 localList, List resourceList) { String sql = ""; String resourceWhere = ""; for (Long re : resourceList) { resourceWhere += " rv.resourceid=" + re + " or"; } if (resourceWhere.endsWith("or")) resourceWhere = resourceWhere.substring(0, resourceWhere.length() - 2); List 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 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 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); if (uid != null) { UserInfo user = new UserInfo(); user.setId(uid); sh.setUser(user); } searchDao.create(sh); // 查询数据库 //专辑数量 long albumCount = 0L; List list = new ArrayList<>(); List localList = null; try { long startt = System.currentTimeMillis(); localList = null; localList = new ArrayList<>(); //先搜索专辑 int pageSize = 20; SearchResult searchResult = searchAlbum(videoType, key, resourceList, page, pageSize, false); if (page == 1 && (searchResult == null || searchResult.videoInfoList == null || searchResult.videoInfoList.size() == 0)) { searchResult = searchAlbum(videoType, key, resourceList, page, pageSize, true); } if (searchResult != null && searchResult.videoInfoList != null) { localList.addAll(searchResult.videoInfoList); } Set solrAlbumVids = new HashSet<>(); for (VideoInfo videoInfo : localList) { solrAlbumVids.add(videoInfo.getId()); } int commonSolrPage = page - searchResult.getTotalCount() / pageSize; if (videoType == 0 && commonSolrPage > 0) { //搜索原始的 try { List 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)); filterSearchResult(localList, resourceList); } catch (Exception e) { e.printStackTrace(); } finally { } if (localList != null && localList.size() > 0) { list.addAll(localList); } //获取附加信息 list = videoInfoExtraService.batchExtra(list, resourceList); return new VideoListResultVO(list, videoType == 0 ? albumCount : 1000L); } public long searchCount(String key, String system) { String sql = ""; if (system.equalsIgnoreCase("2")) { sql = "select count(*) from VideoInfo v where v.show='1' and (v.name like ?) and (v.videoType.id=105 or v.videoType.id=106 or v.videoType.id=107 or v.videoType.id=108))"; } else { sql = "select count(*) from VideoInfo v where v.show='1' and (v.name like ?)"; } long count = videoInfoDao.getCount(sql, new String[]{(new StringBuilder("")).append(key).append("%").toString()}); return count; } @SuppressWarnings({"rawtypes"}) @Cacheable(value = "userCache", key = "'getHotSearchList'+'-'+#system") public List getHotSearchList(String system) { List 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", 0, Constant.HOT_SEARCH_COUNT, new Serializable[]{system}); for (int i = 0; i < li.size(); i++) { list.add(li.get(i) + ""); } } catch (Exception e) { e.printStackTrace(); } finally { } return list; } public List getHotSearchListByDS(String dsid) { return hotSearchDao.list("from HotSearch hs where hs.system.id=" + dsid + " order by hs.orderby desc"); } public List getHotSearchList() { return hotSearchDao.list("from HotSearch"); } /** * 热门搜索 */ public void addSuperHotSearch(SuperHotSearch sv) { List list = superHotSearchDao.list("from SuperHotSearch sv where sv.hotSearch.id=" + sv.getHotSearch().getId() + " and sv.detailSystem.id=" + sv.getDetailSystem().getId()); if (list != null && list.size() > 0) return; superHotSearchDao.create(sv); } public void updateSuperHotSearch(SuperHotSearch hotSearch) { superHotSearchDao.update(hotSearch); } public void deleteSuperHotSearch(SuperHotSearch hotSearch) { superHotSearchDao.delete(hotSearch); } @SuppressWarnings("unchecked") public void updateSuperHotSearchList(final String detailSystemId, final List typeList) { searchDao.excute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { try { List list = session .createQuery("from SuperHotSearch sh where sh.detailSystem.id=" + detailSystemId).list(); session.getTransaction().begin(); for (SuperHotSearch ad : list) { session.delete(ad); } for (SuperHotSearch videoType : typeList) { session.persist(videoType); } session.flush(); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } return null; } }); } @SuppressWarnings("unchecked") public List getHotSearchAdmin(String key, String systemId, int detailSystem, int page) { List zhiBoClassList = new ArrayList<>(); try { List 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 ? and zb.system.id=" + systemId + " order by zb.createtime desc"; List list = hotSearchDao.list(sql, (page - 1) * Constant.pageCount, Constant.pageCount, new Serializable[]{"%" + key + "%"}); for (HotSearch vb : list) { List detailSystemS = detailSystemDao .list("select vb.detailSystem from SuperHotSearch vb where vb.hotSearch.id=" + vb.getId()); List dssList = new ArrayList<>(); for (DetailSystem ds : detailSystemList) { DetailSystemSelect dss = new DetailSystemSelect(); dss.setDetailSystem(ds); dss.setSelected(false); dssList.add(dss); } // 设置已经存在的 for (DetailSystem ds : detailSystemS) { for (DetailSystemSelect dss : dssList) { if (dss.getDetailSystem().getId().equalsIgnoreCase(ds.getId())) { dss.setSelected(true); break; } } } SuperHotSearch sz = new SuperHotSearch(); sz.setDetailSystem(null); sz.setHotSearch(vb); zhiBoClassList.add(new HotSearchAdmin(sz, dssList)); } } catch (Exception e) { e.printStackTrace(); } return zhiBoClassList; } 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 + "%' and h.system=" + systemId; return videoBanQuanVideoDao.getCountSQL(sql); } /** * 添加热门搜索 * * @param search */ public void addHotSearch(HotSearch search) { hotSearchDao.create(search); } /** * 修改热门搜索 * * @param search */ public void updateHotSearch(HotSearch search) { hotSearchDao.update(search); } /** * 删除热门搜索 * * @param search */ @SuppressWarnings({"unchecked", "rawtypes"}) public void deleteHotSearch(final HotSearch search) { searchDao.excute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { try { session.getTransaction().begin(); List list = session.createQuery("from SuperHotSearch sv where sv.hotSearch.id=?") .setParameter(0, search.getId()).list(); for (SuperHotSearch sv : list) session.delete(sv); session.createSQLQuery("delete from wk_video_hotsearch where id=" + search.getId()) .executeUpdate(); session.flush(); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } return null; } }); } /** * 获取热门搜索 * * @param id * @return */ public HotSearch getHotSearch(String id) { List list = hotSearchDao.getSession().createQuery("from HotSearch where id=?").setParameter(0, id) .list(); if (list != null && list.size() > 0) { return list.get(0); } return null; } @SuppressWarnings("unchecked") public void deleteHotSearchAdmin(final String classId, final String detailSystemId) { searchDao.excute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { try { List list = session .createQuery("from SuperHotSearch vb where vb.hotSearch.id=? and vb.detailSystem.id=?") .setParameter(0, classId).setParameter(1, detailSystemId).list(); if (list != null && list.size() > 0) { session.getTransaction().begin(); for (SuperHotSearch vb : list) session.delete(vb); session.flush(); session.getTransaction().commit(); } } catch (Exception e) { e.printStackTrace(); } return null; } }); } /** * 将搜索结果对象转为视频对象 * * @param solrAlbumVideoList * @param resourceList * @return */ public List convertSolrAlbumResultToVideo(List solrAlbumVideoList, List resourceList) { List 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 videoInfoList; public SearchResult(int totalCount, List videoInfoList) { this.totalCount = totalCount; this.videoInfoList = videoInfoList; } public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public List getVideoInfoList() { return videoInfoList; } public void setVideoInfoList(List videoInfoList) { this.videoInfoList = videoInfoList; } } }