/** * 获取索引字段 */ public List<Field> getFields(); /** * 获取需要更新的检索类型内容总数量 * @param lastModifyTime 索引最后更新时间 * @param params 检索内容参数 * @return */ public int getModifiedTotal(Date lastModifyTime, Mapx<String, Object> params); /** * 获取需要更新的检索类型分页内容 */ public List<Document> getModifiedDocuments(Date lastModifyTime, Mapx<String, Object> params, int pageSize, int pageIndex); /** * 获取需要删除的检索类型内容总数量 * @param lastModifyTime 索引最后更新时间 * @return */ public int getDeletedTotal(Date lastModifyTime, Mapx<String, Object> params); /** * 获取需要删除的检索类型分页内容 * @param lastModifyTime 索引最后更新时间 * @param pageSize 分页大小 * @param pageIndex 当前页数 * @return */ public List<Long> getDeletedIDs(Date lastModifyTime, Mapx<String, Object> params, int pageSize, int pageIndex); |
索引类型java类也可以直接继承AbstractIndexType抽象类,这个类的getFields()方法提供了检索比较通用的基础字段,如IndexType,Title,ID,_KeyWord,AddTime等。
AbstractIndexType.java类代码完整示例如下:
package com.zving.search.service; import java.util.ArrayList; import java.util.List; import org.apache.lucene.document.Field; public abstract class AbstractIndexType implements IIndexType { public List<Field> getFields() { List<Field> list = new ArrayList<Field>(); list.add(new Field("INDEXTYPE", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); // 索引类型 list.add(new Field("TITLE", "", Field.Store.YES, Field.Index.ANALYZED)); list.add(new Field("CONTENT", "", Field.Store.YES, Field.Index.ANALYZED)); list.add(new Field("URL", "", Field.Store.YES, Field.Index.NO)); // 可能需要处理 list.add(new Field("_KEYWORD", "", Field.Store.NO, Field.Index.ANALYZED)); // 需要自定义内容,一般是Title+Content list.add(new Field("ID", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("ADDTIME", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("MODIFYTIME", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); return list; } } |
完整的示例java类代码如下:
package com.zving.indextypetest.impl; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import com.zving.contentcore.properties.impl.IndexEnable; import com.zving.contentcore.util.CatalogUtil; import com.zving.framework.collection.Mapx; import com.zving.framework.data.DataRow; import com.zving.framework.data.DataTable; import com.zving.framework.data.Q; import com.zving.framework.orm.DAO; import com.zving.framework.orm.DAOSet; import com.zving.framework.utility.DateUtil; import com.zving.framework.utility.ObjectUtil; import com.zving.framework.utility.StringUtil; import com.zving.platform.code.YesOrNo; import com.zving.schema.ZCCatalog; import com.zving.schema.ZCComment; import com.zving.search.service.IIndexType; public class MyTestIndexType implements IIndexType { public static final String ID = "CommentIndexType"; // 评论索引类型 public String getID() { return ID; } public String getName() { return "评论索引类型"; } public List<Field> getFields() { List<Field> list = new ArrayList<Field>(); list.add(new Field("INDEXTYPE", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); // 索引类型 list.add(new Field("ID", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("TITLE", "", Field.Store.YES, Field.Index.ANALYZED)); list.add(new Field("CONTENT", "", Field.Store.YES, Field.Index.ANALYZED)); list.add(new Field("_KEYWORD", "", Field.Store.NO, Field.Index.ANALYZED)); // 需要自定义内容,一般是Title+Content list.add(new Field("SITEID", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("RELACONTENTID", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("CATALOGID", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("CATALOGNAME", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("CATALOGTYPE", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("CATALOGINNERCODE", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("VERIFYFLAG", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("VERIFYUSER", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("VERIFYTIME", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("INDEXENABLE", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); // 栏目配置:是否开启检索 list.add(new Field("ADDTIME", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); list.add(new Field("MODIFYTIME", "", Field.Store.YES, Field.Index.NOT_ANALYZED)); return list; } public int getModifiedTotal(Date lastModifyTime, Mapx<String, Object> params) { if (ObjectUtil.notEmpty(params.getDate("LastModifyTime"))) { lastModifyTime = params.getDate("LastModifyTime"); } Q qb = new Q("select count(*) from ZCComment where VerifyFlag=? and (ModifyTime>? or AddTime>?)", YesOrNo.Yes, lastModifyTime, lastModifyTime); if (ObjectUtil.notEmpty(params.getLong("SiteID"))) { qb.append(" and SiteID=?", params.getLong("SiteID")); } if (ObjectUtil.notEmpty(params.getLong("CatalogID"))) { qb.append(" and CatalogID=?", params.getLong("CatalogID")); } return qb.executeInt(); } public List<Document> getModifiedDocuments(Date lastModifyTime, Mapx<String, Object> params, int pageSize, int pageIndex) { if (ObjectUtil.notEmpty(params.getDate("LastModifyTime"))) { lastModifyTime = params.getDate("LastModifyTime"); } Q qb = new Q("where VerifyFlag=? and (ModifyTime>? or AddTime>?)", YesOrNo.Yes, lastModifyTime, lastModifyTime); if (ObjectUtil.notEmpty(params.getLong("SiteID"))) { qb.append(" and SiteID=?", params.getLong("SiteID")); } if (ObjectUtil.notEmpty(params.getLong("CatalogID"))) { qb.append(" and CatalogID=?", params.getLong("CatalogID")); } DAOSet<ZCComment> set = new ZCComment().query(qb, pageSize, pageIndex); return parseDocument(set); } public int getDeletedTotal(Date lastModifyTime, Mapx<String, Object> params) { Q qb = new Q("select count(*) from BZCComment where BackupMemo=? and BackupTime>?", DAO.MEMO_DELETE, lastModifyTime); if (ObjectUtil.notEmpty(params.getLong("SiteID"))) { qb.append(" and SiteID=?", params.getLong("SiteID")); } if (ObjectUtil.notEmpty(params.getLong("CatalogID"))) { qb.append(" and CatalogID=?", params.getLong("CatalogID")); } int count = qb.executeInt(); return count; } public List<Long> getDeletedIDs(Date lastModifyTime, Mapx<String, Object> params, int pageSize, int pageIndex) { ArrayList<Long> list = new ArrayList<Long>(); Q qb = new Q("select ID from BZCComment where BackupMemo=? and BackupTime>?", DAO.MEMO_DELETE, lastModifyTime); if (ObjectUtil.notEmpty(params.getLong("SiteID"))) { qb.append(" and SiteID=?", params.getLong("SiteID")); } if (ObjectUtil.notEmpty(params.getLong("CatalogID"))) { qb.append(" and CatalogID=?", params.getLong("CatalogID")); } DataTable dt = qb.fetch(pageSize, pageIndex); for (DataRow dr : dt) { list.add(dr.getLong("ID")); } return list; } public List<Document> parseDocument(DAOSet<ZCComment> set) { List<Document> docs = new ArrayList<Document>();// 每个document代表一条评论记录 for (ZCComment c : set) { Document doc = getDocument(c); if (doc != null && doc.getFields() != null && doc.getFields().size() > 0) { docs.add(getDocument(c)); } } return docs; } public Document getDocument(ZCComment c) { List<Field> fields = getFields(); Document doc = new Document(); ZCCatalog catalog = CatalogUtil.getDAO(c.getCatalogID()); for (Field field : fields) { if (StringUtil.isNotNull(field.stringValue())) { doc.add(field); continue; } if ("INDEXTYPE".equals(field.name())) { field.setValue(ID);// 检索类型 } else if ("ID".equals(field.name())) { field.setValue(String.valueOf(c.getID())); } else if ("TITLE".equals(field.name())) { field.setValue(c.getTitle() == null ? "" : c.getTitle()); } else if ("CONTENT".equals(field.name())) { field.setValue(c.getContent() == null ? "" : c.getContent()); } else if ("_KEYWORD".equals(field.name())) { String keyword = c.getContent() == null ? "" : c.getContent() + " "; keyword += c.getTitle() == null ? "" : c.getTitle(); field.setValue(keyword); } else if ("SITEID".equals(field.name())) { field.setValue(String.valueOf(c.getSiteID())); } else if ("RELACONTENTID".equals(field.name())) { field.setValue(String.valueOf(c.getRelaID())); } else if ("CATALOGID".equals(field.name())) { field.setValue(String.valueOf(c.getCatalogID())); } else if ("CATALOGINNERCODE".equals(field.name())) { field.setValue(c.getCatalogInnerCode()); } else if ("CATALOGTYPE".equals(field.name())) { field.setValue(c.getCatalogType()); } else if ("CATALOGNAME".equals(field.name())) { field.setValue(catalog.getName()); } else if ("INDEXENABLE".equals(field.name())) { if (catalog != null) { field.setValue(IndexEnable.getValue(catalog.getConfigProps()) ? YesOrNo.Yes : YesOrNo.No); } else { field.setValue(YesOrNo.Yes); } } else if ("VERIFYFLAG".equals(field.name())) { field.setValue(c.getVerifyFlag()); } else if ("VERIFYUSER".equals(field.name())) { field.setValue(c.getVerifyUser()); } else if ("VERIFYTIME".equals(field.name())) { field.setValue(ObjectUtil.empty(c.getVerifyTime()) ? "" : DateUtil.toDateTimeString(c.getVerifyTime())); } else if ("ADDTIME".equals(field.name())) { field.setValue(ObjectUtil.empty(c.getAddTime()) ? "" : DateUtil.toDateTimeString(c.getAddTime())); } else if ("MODIFYTIME".equals(field.name())) { field.setValue(ObjectUtil.empty(c.getModifyTime()) ? "" : DateUtil.toDateTimeString(c.getModifyTime())); } doc.add(field); } return doc; } }
|
注册检索类型扩展项
向全文检索类型扩展服务SearchService注册检索类型扩展项
创建索引
启动应用,系统定时任务IndexTask会定时调用SingleIndexer的start()方法创建索引。
按条件搜索
生成的索引通过统一查询入口SearchService获取数据。实现步骤如下:1、获取索引参数 2、获取搜索器 3、返回搜索结果。
获取数据的示例代码如下:
public DataTable getSearchList(DataGridAction dga) { /* * 准备索引参数 */ ArrayList<SearchParam> sps = new ArrayList<SearchParam>(); //按字段条件查询 sps.add(new SearchParam("INDEXTYPE", MyTestIndexType.ID, SearchParam.SearchType.Equal, Occur.MUST)); if (ObjectUtil.notEmpty($V("SiteID"))) {// 站点ID sps.add(new SearchParam("SITEID", $V("SiteID"), SearchParam.SearchType.Equal, Occur.MUST)); } if (!YesOrNo.isYes($V("TitleOnly"))) { sps.add(new SearchParam("TITLE", $V("Keyword"), SearchParam.SearchType.Fulltext)); sps.add(new SearchParam("CONTENT", $V("Keyword"), SearchParam.SearchType.Fulltext)); sps.add(new SearchParam("_KEYWORD", $V("Keyword"), SearchParam.SearchType.Fulltext, Occur.MUST)); } else { sps.add(new SearchParam("TITLE", $V("Keyword"), SearchParam.SearchType.Fulltext, Occur.MUST)); } //左相似检索 if (ObjectUtil.notEmpty($V("CatalogInnerCode"))) { sps.add(new SearchParam("CATALOGINNERCODE", $V("CatalogInnerCode"), SearchParam.SearchType.LeftLike, Occur.MUST)); } //前台搜索只能搜索到开启了检索的栏目下的内容 sps.add(new SearchParam("INDEXENABLE", YesOrNo.Yes, SearchParam.SearchType.Equal, Occur.MUST)); sps.add(new SearchParam("PAGESIZE", dga.getPageSize() + "", SearchParam.SearchType.PageSize)); sps.add(new SearchParam("PAGEINDEX", dga.getPageIndex() + "", SearchParam.SearchType.PageIndex)); //前台搜索只能搜到已经通过审核的评论 sps.add(new SearchParam("VERIFYFLAG", YesOrNo.Yes, SearchParam.SearchType.Equal, Occur.MUST)); //根据时间范围查询 if (StringUtil.isNotEmpty($V("StartTime")) && StringUtil.isNotEmpty($V("EndTime"))) { sps.add(new SearchParam("VERIFYTIME", $V("StartTime"), $V("EndTime"), SearchParam.SearchType.DateRange)); } //多字段共同排序 if (StringUtil.isNotEmpty($V("Sort"))) { String[] sorts = StringUtil.splitEx($V("Sort"), ","); for (String sort : sorts) { sps.add(new SearchParam(sort, null, SearchParam.SearchType.Sort, Occur.MUST)); } } /* * 获取搜索器进行搜索 */ SearchResult sr = SearchService.search(sps, true); dga.setTotal(sr.Total); //当没有搜索到记录,不保存到热门词汇中 if(sr==null||sr.Total<1){ return sr.Data; } /* * 搜索结果 */ DataTable dt = sr.Data; if (dt != null && dt.getRowCount() > 0) { // 记录关键词搜索统计 SearchWordStat.getInstance().stat(sps); } return dt; } |
所有评论仅代表网友意见