• Solr4:利用Filter实现两组关键词组合查询


    本文参考:Lucene4.1:利用Filter实现两组关键词组合查询

    1. 需求

    根据客户名称,查询客户网络上面的负面信息。如客户名称为”盐城 盐城市“,并自定义负面关键词“贪污 受贿 被曝 曝光 小三 裸照”等,则是要求将包含这些负面关键词且包含客户名称的信息查询出来。注意事项:客户名称可定义多个(10个以内),负面关键词可以定义多个(300个以内)。

    分析

    如果只用一个参数q去定义查询,很可能查询字符串长度会溢出,查询q应该形如:

    ((盐城 OR 盐城市) AND 贪污) OR ((盐城 OR 盐城市) AND 受贿)...... 

    所以本文采用Filter的形式来解决这一问题。

    2. 解决步骤 

    步骤一:将所需要查询的客户名称、负面关键词加入到中文分词器词典文件中;(本文略)
             只有中文能够将这些关键词正确分词,其它各项操作才能顺利进行。
    步骤二:用爬虫工具将网络上的信息抓取下来后,在创建Lucene索引的时候, 将包含负面关键词的文档自定义分值(包含负面关键词越多,分值越高);(说明略,可以参考:Lucene4.1:运用中文分词器创建索引,给指定文本增加boost值
             这样可以保证查询时,包含负面关键词越多的文档,查询时排在越前面。
    步骤三:按客户名称查询(如:盐城 盐城市);
             正常查询输入。
    步骤四:查询时加入过滤器(Filter),过滤器的输入就是负面关键词列表;
             加入过滤器后,实现的查询结果类似于:((盐城 OR 盐城市) AND 贪污) OR ((盐城 OR 盐城市) AND 受贿)......
    步骤五:自定义高亮结果。
             因为客户名称需要高亮,负面关键词也需要高亮,所以需要自定义高亮显示。

    3. SlorJ实现代码

    package com.clzhang.sample.solr;
    
    import java.io.*;
    import java.util.*;
    
    import org.apache.lucene.analysis.Analyzer;
    import org.apache.lucene.analysis.TokenStream;
    import org.apache.lucene.queryparser.classic.QueryParser;
    import org.apache.lucene.search.Query;
    import org.apache.lucene.search.highlight.Highlighter;
    import org.apache.lucene.search.highlight.QueryScorer;
    import org.apache.lucene.search.highlight.SimpleSpanFragmenter;
    import org.apache.lucene.search.highlight.TokenSources;
    import org.apache.lucene.util.Version;
    import org.apache.solr.client.solrj.SolrQuery;
    import org.apache.solr.client.solrj.impl.HttpSolrServer;
    import org.apache.solr.client.solrj.response.QueryResponse;
    import org.apache.solr.common.SolrDocumentList;
    import org.apache.solr.common.SolrDocument;
    
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    import com.chenlb.mmseg4j.Dictionary;
    import com.chenlb.mmseg4j.analysis.ComplexAnalyzer;
    
    /**
     * 综合:按客户名称查询客户网络上面的负面信息
     * @author Administrator
     *
     */
    public class SlorJHighlightTest {
        // mmseg4j字典路径
        private static final String MMSEG4J_DICT_PATH = "C:\\solr\\mm4jdic";
        private static Dictionary dictionary = Dictionary.getInstance(MMSEG4J_DICT_PATH);
    
        private HttpSolrServer server;
        private static final String DEFAULT_URL = "http://localhost:8080/solr/news";
    
        @Before
        public void init() {
            // 初始化Solr服务器句柄
            server = new HttpSolrServer(DEFAULT_URL);
            server.setMaxRetries(1); // defaults to 0. > 1 not recommended.
            server.setConnectionTimeout(5000); // 5 seconds to establish TCP
            server.setSoTimeout(1000); // socket read timeout
            server.setDefaultMaxConnectionsPerHost(100);
            server.setMaxTotalConnections(100);
            server.setFollowRedirects(false); // defaults to false
            server.setAllowCompression(true);
        }
    
        @After
        public void destory() {
            server = null;
            System.runFinalization();
            System.gc();
        }
    
        @Test
        public void queryCase() {
            // 步骤一:查询关键词
            String keyword = "(盐城 盐城市)";
            SolrQuery params = new SolrQuery("webTitle:" + keyword);
            params.set("start", 0);
            params.set("rows", 5);
            params.set("fl", "objectId,webTitle,webContent");
    //        params.set("sort", "webTime desc");
    
            // 步骤二:负面关键词
            String negativeWord = "(贪污 受贿 被曝 曝光 小三 裸照)"; 
            params.addFilterQuery("webTitle:" + negativeWord);
    
            try {
                // 步骤三:需要高亮的关键词,默认等于查询关键词+负面关键词
                String hlKeywords = keyword + " " + negativeWord;
                
                // 查询
                QueryResponse response = server.query(params);
                Analyzer analyzer = new ComplexAnalyzer(dictionary);
                QueryScorer scorer = new QueryScorer(new QueryParser(
                        Version.LUCENE_41, null, analyzer).parse(hlKeywords), null);
                Highlighter highlighter = new Highlighter(scorer);
                highlighter.setTextFragmenter(new SimpleSpanFragmenter(scorer));
    
                // 输出
                SolrDocumentList list = response.getResults();
                System.out.println("返回:" + list.getNumFound() + "条记录\t耗时:" + response.getElapsedTime() + "毫秒");
                for (int i = 0; i < list.size(); i++) {
                    SolrDocument doc = (SolrDocument)list.get(i);
                    String objectId = doc.get("objectId").toString();
                    String title = doc.get("webTitle").toString();
                    String content = doc.get("webContent").toString();
                    StringBuilder sbTitle = new StringBuilder();
                    
                    // 有高亮结果则用高亮结果;没有则用无高亮查询结果。
                    // 仅对标题(webTitle)高亮,内容(webContent)忽略
                    TokenStream streamContent = TokenSources.getTokenStream("", title, analyzer);
                    String[] fragContent = highlighter.getBestFragments(streamContent, title, 5000);
                    if(fragContent != null && fragContent.length > 0) {
                        for(String str: fragContent) {
                            sbTitle.append(str);
                        }
                    }else {
                        sbTitle.append(title);
                    }
                    System.out.println(sbTitle.toString());
    //                System.out.println(content);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } 
        }
    }

    输出:

    返回:13条记录 耗时:94毫秒
    [<B>曝光</B>台]实名举报江苏<B>盐城市</B>阜宁县吴滩镇派出所办案无能
    <B>盐城</B>质监局长冯建东贪@污糜烂<B>被曝</B>光:包二奶、玩小姐&nbsp;还找黑客删帖遭<B>曝光</B>
    <B>盐城</B>质监局长冯建东“包二奶、招小姐、淫下属”丑行<B>曝光</B>
    江苏<B>盐城市</B>中级人民法院是什么鸟人?居然造出一个<B>贪污</B>大犯赵作海
    [爆 猛 料]<B>盐城市</B>亭湖农委下属单位领导<B>贪污</B>特种苗木补助款

  • 相关阅读:
    轻量级分布式任务调度框架(二、LTS编译、打包、部署)
    轻量级分布式任务调度框架(一、LTS简介、特点、工作流程)
    MySQL数据库学习一
    Navicat 连接 SQL Server 数据库,报错 08001
    noVNC 遇到一个错误: Uncaught TypeError: Cannot read property 'forEach' of undefined
    加强自己VPS服务器安全的一次经历
    Python 编码错误的本质和解决方案
    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'data' at line 1
    requests爬虫请求报错:UnicodeEncodeError: 'latin-1' codec can't encode character 'u2026' in position 30
    docker无法删除镜像,Error: No such container,附docker常用命令
  • 原文地址:https://www.cnblogs.com/nayitian/p/2918938.html
Copyright © 2020-2023  润新知