SOLR7实践(四)--查询

查询@SOLR7实践(四)

查询

先说说客户的要求

  1. 用户只有一个搜索框,可以输入多个关键字进行检索;
  2. 搜索范围是公文系统包括文件标题(TITLE),文件编号(MARKID),文种(FORM),正文(CONTENT)等字段,通讯录包括名字(TITLE),部门(ORGNAME),手机号码(MOBILE),邮件地址(EMAIL)等字段;
  3. 字段的重要程度 标题>正文;
  4. 相关度相同时按时间倒序排列;
  5. 搜索结果可以按照时间范围进行过滤。

SOLR检索的参数说明,可参考如下文章

https://blog.csdn.net/yuwenruli/article/details/8448575
https://lucene.apache.org/solr/guide/6_6/common-query-parameters.html

https://www.cnblogs.com/Lxiaojiang/p/6800398.html
https://lucene.apache.org/solr/guide/6_6/the-dismax-query-parser.html
https://lucene.apache.org/solr/guide/6_6/the-extended-dismax-query-parser.html

结合伪代码说一下怎么实现的(相信我,代码一定跑不通的)

    // 变量说明
    // 用户输入搜索关键字(如:I like beijing)
    String keyword;
    // keyword用空格拆分的数组(如:[I, like, beijing])
    String[] keywords;
    // keywords用*连接的字符串(如:*I*like*beijing*)
    String keywordJoinStart;
    // keyword加"包裹的字符串(如:"I like beijing")
    String keywordQuot;
    // keywords每个元素加"包裹(如:["I", "like", "beijing"])
    String keywordsQuot;

	// 创建solr客户端
	HttpSolrClient server = new HttpSolrClient.Builder(solrUrl).build();        
	// 创建solr查询器
	SolrQuery query = new SolrQuery();

    // TITLE,CONTENT,SRCHFLD 字段类型为text_ik
    // TITLE_COPY 拷贝自TITLE,字段类型为string
    // SRCHFLD 拷贝自除TITLE,CONTENT之外的查询字段
	// *用于模糊匹配可以用在string类型的字段,不能用在text_ik类型的字段
	// ”用于精确匹配可以用在string类型也可以用在text_ik类型的字段
    
    // 对TITLE_COPY字段进行了正向的模糊匹配,这个开销是非常大的,整个搜索速度慢了10倍!!!
    // 好在目前客户对搜索速度还可以接受。
    // 调查过原因是单个的英数字在经过IK分词器后被遗弃了,
    // 更深层次的原因是 LowerCaseTokenizerFactory 会过滤掉单个英数字。
    // 解决方法有文章提出用EdgeNGramFilterFactory 替换 LowerCaseTokenizerFactory ,但对英文字母的大小写的支持会变差。
    query.setParam("q","(TITLE_COPY:keywordJoinStart) OR (TITLE:keywordQuot) OR (CONTENT:keywordQuot) OR (SRCHFLD:keywordQuot) OR (SRCHFLD:keywordsQuot[0] AND ... AND SRCHFLD:keywordsQuot[n])");
    //设置返回字段列表 * 全部索引字段,score 索引的评分
    query.setParam("fl", "*,score");
    // 设置返回结果的开始记录数(从0开始)和总记录数,完成分页功能
    query.setParam("start", start);
    query.setParam("rows", rows);

    // 设置过滤字段,完成数据权限过滤
    // SOLR处理fq时是默认使用缓存的,测试过query.addFilterQuery(filterQuery) 和 query.addFilterQuery(filterQueries[i]) 等写法,可能受限于测试环境和测试数据的原因,搜索速度未有明显提升
    query.setParam("fq",filterQuery);

    // 设置结果排序,先按评分排,再按时间排
    query.addSort("score", ORDER.desc);
    query.addSort("CREATETIME", ORDER.desc);
    
    // 高亮显示
    // 中文高亮显示总是有问题,要么漏词,要么只能标红单字。没有找到相关解决方法,使用了一个变通的方案,自己编码对搜索结果再进行高亮设置。
    query.setParam("hl", highLight);
    // 设置高亮显示的字段列表
    query.setParam("hl.fl",flFieldList);
    // 设置高亮显示的前缀
    query.setParam("hl.simple.pre",flSimplePre);
    // 设置高亮显示的后缀
    query.setParam("hl.simple.post",flSimplePost);
    // 设置highlighted片段的最大数,默认值是1,不需要修改
    query.setParam("hl.snippets",flSnippets);
    // 设置高亮显示的snippet返回的最大字节数
    query.setParam("hl.fragsize",flFragsize);
    
    // 设置eDisMax模式
    query.setParam("defType", "edismax");
    // 设置字段权重,影响结果排序
    // 排序试了很多方法,记录下目前的方案(仍有部分数据未能排在应该的位置)
    // 只说一下可以影响排序的SOLR参数和方法
    // 参数 q, sort, dismax中 qf,pf,bq,bf,edismax中qf,pf,bq,bf,boost
    // 方法 对字段升压,对搜索关键字升压,自己构造函数生成权重值等
    
    // 对q中使用到的字段,按照重要性设置不同的权重
    query.setParam("pf",”TITLE_COPY^100 TITLE^10 CONTENT^2 SRCHFLD“);
    
    // 执行查询接收结果
    QueryResponse qResponse = new QueryResponse();
    qResponse = server.query(query);
    server.close();

对于多个搜索关键字分布在多个字段中的排序问题的一个解决思路,每个字段用一个搜索框,每个字段都使用精确匹配,设置匹配度为100%,不同字段设置不同的权重,最后结果按时间排序。这可能才是用户的内心想要的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值