美文网首页
07_Lucene搜索

07_Lucene搜索

作者: 对方不想理你并向你抛出一个异常 | 来源:发表于2018-01-21 01:12 被阅读0次

    搜索

    对要搜索的信息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库Sql语法一样Lucene也有自己的查询语法,比如:“name:lucene”表示查询Field的name为“lucene”的文档信息。
    可通过两种方法创建查询对象:

    • 使用Lucene提供Query子类
      Query是一个抽象类,lucene提供了很多查询对象,比如TermQuery项精确查询,NumericRangeQuery数字范围查询等。
      如下代码:
      Query query = new TermQuery(new Term("name", "lucene"));

    • 使用QueryParse解析查询表达式
      QueryParse会将用户输入的查询表达式解析成Query对象实例。
      如下代码:
      QueryParser queryParser = new QueryParser("name", new IKAnalyzer());
      Query query = queryParser.parse("name:lucene");

    各种查询

    TermQuery:

    根据词进行搜索(只能从文本中进行搜索)
    TermQuery,通过项查询,TermQuery不使用分析器所以建议匹配不分词的Field域查询,比如订单号、分类ID号等。指定要查询的域和要查询的关键词。

        @Test
        public void testIndexTermQuery() throws Exception{
            //创建分词器(创建索引和搜索时所用的分词器必须一致)
            Analyzer analyzer = new IKAnalyzer();
    
            //指定索引和文档的目录
            Directory dir  = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
            IndexReader indexReader = IndexReader.open(dir);
    
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
            //创建词元:就是词,
            Term t = new Term("fileName" , "apache");
            //使用TermQuery查询,根据term对象进行查询
            TermQuery query = new TermQuery(t);
            //搜索:第一个参数为查询语句对象, 第二个参数:指定显示多少条
            TopDocs topdocs = indexSearcher.search(query , 10);
            //一共搜索到多少条记录
            System.out.println("=====count=====" + topdocs.totalHits);
            //从搜索结果对象中获取结果集
            ScoreDoc[] scoreDocs = topdocs.scoreDocs;
    
            for(ScoreDoc scoreDoc : scoreDocs){
                //获取docID
                int docID = scoreDoc.doc;
                //通过文档ID从硬盘中读取出对应的文档
                Document document = indexReader.document(docID);
                //get域名可以取出值 打印
                System.out.println("fileName:" + document.get("fileName"));
                System.out.println("fileSize:" + document.get("fileSize"));
                System.out.println("============================================================");
            }
        }
    

    QueryParser:

    根据域名进行搜索,可以设置默认搜索域,推荐使用. (只能从文本中进行搜索)
    通过QueryParser也可以创建Query,QueryParser提供一个Parse方法,此方法可以直接根据查询语法来查询。Query对象执行的查询语法可通过System.out.println(query);查询,需要使用到分析器。建议创建索引时使用的分析器和查询索引时使用的分析器要一致。
    1 , 需要加入queryParser依赖的jar包。
    \lib\lucene-queryparser-4.10.3.jar
    2,实现

    private String searchField = "fileName";
        private String searchWord = "1.create web page.txt";
    
        @Test
        public void testIndexSearch() throws Exception{
            //创建分词器(创建索引和搜索时所用的分词器必须一致)
            Analyzer analyzer = new IKAnalyzer();
    
            //指定索引和文档的目录
            Directory dir  = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
            //索引和文档的读取对象
            DirectoryReader indexReader = IndexReader.open(dir);
            //创建索引的搜索对象
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
            /**
             * 默认搜索域作用:如果搜索语法中指定域名从指定域中搜索,如果搜索时只写了查询关键字,则从默认搜索域中进行搜索
             * 第一个参数:默认搜索域,
             * 第二个参数:分词器
             */
            QueryParser queryParser = new QueryParser("fileContent" , analyzer);
    //        Query query = queryParser.parse("apache");//从默认域搜索
            Query query = queryParser.parse(searchField+":"+searchWord);//从指定域搜索
            /**
             * 搜索:
             * 第一个参数为查询语句对象
             * 第二个参数:指定显示多少条
             */
            TopDocs topDocs = indexSearcher.search(query, 10);
            //一共搜索到多少条记录
            System.out.println("=====count======"+topDocs.totalHits);
            //从搜索结果对象中获取结果集
            ScoreDoc[] scoreDocs = topDocs.scoreDocs;
    
            for (ScoreDoc scoreDoc : scoreDocs){
                //获取docId
                int docId = scoreDoc.doc;
                //通过文档ID从硬盘中读取出对应的文档
                Document document = indexReader.document(docId);
                System.out.println("fileName="+document.get("fileName"));
                System.out.println("fileSize="+document.get("fileSize"));
                System.out.println("=====================================");
            }
        }
    

    NumericRangeQuery:

    从数值范围进行搜索

    @Test
        public void testNumericRangeQuery() throws Exception{
            //创建分词器(创建索引和搜索时所用的分词器必须一致)
            Analyzer analyzer = new IKAnalyzer();
    
            //指定索引和文档的目录
            FSDirectory dir = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
            IndexReader indexReader = IndexReader.open(dir);
            //创建索引的搜索对象
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    
            //根据数字范围查询
            //查询文件大小,大于100 小于1000的文章
            /**
             * 第一个参数:域名
             * 第二个参数:最小值,
             * 第三个参数:最大值,
             * 第四个参数:是否包含最小值,
             * 第五个参数:是否包含最大值
             */
    
            NumericRangeQuery<Long> query = NumericRangeQuery.newLongRange("fileSize", 100L, 1000L, true, true);
            //搜索:第一个参数为查询语句对象, 第二个参数:指定显示多少条
            TopDocs topdocs = indexSearcher.search(query, 10);
    
            //从搜索结果对象中获取结果集
            ScoreDoc[] scoreDocs = topdocs.scoreDocs;
    
            for(ScoreDoc scoreDoc : scoreDocs){
                //获取docID
                int docID = scoreDoc.doc;
                //通过文档ID从硬盘中读取出对应的文档
                Document document = indexReader.document(docID);
                //get域名可以取出值 打印
                System.out.println("fileName:" + document.get("fileName"));
                System.out.println("fileSize:" + document.get("fileSize"));
                System.out.println("============================================================");
            }
        }
    

    BooleanQuery:

    • 组合查询,可以设置组合条件,not and or.从多个域中进行查询
    • must相当于and关键字,是并且的意思
    • should,相当于or关键字或者的意思
    • must_not相当于not关键字, 非的意思
    • 注意:单独使用must_not 或者 独自使用must_not没有任何意义
        @Test
        public void testBooleanQuery() throws Exception{
            //创建分词器(创建索引和搜索时所用的分词器必须一致)
            Analyzer analyzer = new IKAnalyzer();
    
            //指定索引和文档的目录
            FSDirectory dir = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
            IndexReader indexReader = IndexReader.open(dir);
            //创建索引的搜索对象
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    
            //布尔查询,就是可以根据多个条件组合进行查询
            //文件名称包含apache的,并且文件大小大于等于100 小于等于1000字节的文章
            BooleanQuery query = new BooleanQuery();
    
            //创建词元:就是词,
            Term t = new Term("fileName" , "apache");
            //使用TermQuery查询,根据term对象进行查询
            TermQuery termQuery = new TermQuery(t);
    
            //根据数字范围查询
            //查询文件大小,大于100 小于1000的文章
            NumericRangeQuery<Long> numQuery = NumericRangeQuery.newLongRange("fileSize", 100L, 1000L, true, true);
    
            //Occur是逻辑条件
            //must相当于and关键字,是并且的意思
            //should,相当于or关键字或者的意思
            //must_not相当于not关键字, 非的意思
            //注意:单独使用must_not  或者 独自使用must_not没有任何意义
            query.add(termQuery , BooleanClause.Occur.MUST);
            query.add(numQuery , BooleanClause.Occur.MUST);
    
            TopDocs topdocs = indexSearcher.search(query, 10);
    
            //从搜索结果对象中获取结果集
            ScoreDoc[] scoreDocs = topdocs.scoreDocs;
    
            for(ScoreDoc scoreDoc : scoreDocs){
                //获取docID
                int docID = scoreDoc.doc;
                //通过文档ID从硬盘中读取出对应的文档
                Document document = indexReader.document(docID);
                //get域名可以取出值 打印
                System.out.println("fileName:" + document.get("fileName"));
                System.out.println("fileSize:" + document.get("fileSize"));
                System.out.println("============================================================");
            }
    
        }
    

    MatchAllDocsQuery:

    查询出所有文档

    @Test
        public void testMathAllQuery() throws Exception{
            //创建分词器(创建索引和所有时所用的分词器必须一致)
            Analyzer analyzer = new IKAnalyzer();
            
            //查询所有文档
            MatchAllDocsQuery query = new MatchAllDocsQuery();
            
            //指定索引和文档的目录
            Directory dir = FSDirectory.open(new File("E:\\dic"));
            //索引和文档的读取对象
            IndexReader indexReader = IndexReader.open(dir);
            //创建索引的搜索对象
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
            //搜索:第一个参数为查询语句对象, 第二个参数:指定显示多少条
            TopDocs topdocs = indexSearcher.search(query, 5);
            //一共搜索到多少条记录
            System.out.println("=====count=====" + topdocs.totalHits);
            //从搜索结果对象中获取结果集
            ScoreDoc[] scoreDocs = topdocs.scoreDocs;
            
            for(ScoreDoc scoreDoc : scoreDocs){
                //获取docID
                int docID = scoreDoc.doc;
                //通过文档ID从硬盘中读取出对应的文档
                Document document = indexReader.document(docID);
                //get域名可以取出值 打印
                System.out.println("fileName:" + document.get("fileName"));
                System.out.println("fileSize:" + document.get("fileSize"));
                System.out.println("============================================================");
            }
        }
    

    MultiFieldQueryParser:

    可以从多个域中进行查询,只有这些域中有关键词的存在就查询出来.

    @Test
        public void testMultiFieldQueryParser() throws Exception{
            //创建分词器(创建索引和搜索时所用的分词器必须一致)
            Analyzer analyzer = new IKAnalyzer();
    
            //指定索引和文档的目录
            FSDirectory dir = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
            IndexReader indexReader = IndexReader.open(dir);
            //创建索引的搜索对象
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    
            String[] fields = {"fileName" , "fileContext"};
            //从文件名称和文件内容中查询,只有含有apache的就查出来
            MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields , analyzer);
            //输入需要搜索的关键字
            Query query = queryParser.parse("apache");
            //搜索:第一个参数为查询语句对象, 第二个参数:指定显示多少条
            TopDocs topdocs = indexSearcher.search(query, 10);
    
            //从搜索结果对象中获取结果集
            ScoreDoc[] scoreDocs = topdocs.scoreDocs;
    
            for(ScoreDoc scoreDoc : scoreDocs){
                //获取docID
                int docID = scoreDoc.doc;
                //通过文档ID从硬盘中读取出对应的文档
                Document document = indexReader.document(docID);
                //get域名可以取出值 打印
                System.out.println("fileName:" + document.get("fileName"));
                System.out.println("fileSize:" + document.get("fileSize"));
                System.out.println("============================================================");
            }
        }
    

    相关文章

      网友评论

          本文标题:07_Lucene搜索

          本文链接:https://www.haomeiwen.com/subject/ghbxaxtx.html