全文检索技术_Lucene搜索

    通过前几篇《全文检索技术专栏》关于倒排索引算法的原理、Lucene分词、索引的创建等内容的介绍,Lucene中最重要也是最能体现Lucene作用的非搜索功能莫属。Lucene对创建的索引可实现多种搜索功能(词项查询、多域查询、布尔查询、范围查询、模糊查询、通配查询),在进行搜索时,将查询条件封装成query对象,最终得到多个document数据。

词项查询

词项查询是最基本的查询方式,查询参数就是一个域中的词语。判断倒排索引表中是否有相关词项,最终将document匹配集合返回。

  @Test
    public void termQuery() throws IOException {
        //指定一个文件输出目录
        Path path= Paths.get("d:/test/index");
        //将路径交给FSDirectory完成路径的管理,当路径不存在时,由FSDirectory帮你创建
        FSDirectory fsDirectory=FSDirectory.open(path);
    
        //创建索引输入流
        IndexReader indexReader= DirectoryReader.open(fsDirectory);
        IndexSearcher indexSearcher=new IndexSearcher(indexReader);
        
        //创建词项查询条件
        Term term=new Term("title","巴西");
        Query query= new TermQuery(term);
    
        //查询
        TopDocs docs = indexSearcher.search(query, 3);
        ScoreDoc[] scoreDocs=docs.scoreDocs;
        for (ScoreDoc scoreDoc:scoreDocs){
            //获取document对象属性
            //documentId
            int did = scoreDoc.doc;
            Document docObj = indexSearcher.doc(did);
            System.out.println("============"+did+"============");
            System.out.println(docObj.get("title"));
            System.out.println(docObj.get("origin"));
            System.out.println(docObj.get("content"));
    
        }
    }

查询结果:
在这里插入图片描述

多域查询

在上面的词项查询中,我们只搜索了titile,如果想同时搜索title、origin、content中有没有要查询的关键词,可以通过多域查询的方式。

代码和词项查询的区别不是很大,唯一不同的是构造查询条件和构造查询对象的方式不同:

 @Test
    public void multiQuery() throws IOException, ParseException {
        //指定一个文件输出目录
        Path path= Paths.get("d:/test/index");
        //将路径交给FSDirectory完成路径的管理,当路径不存在时,由FSDirectory帮你创建
        FSDirectory fsDirectory=FSDirectory.open(path);
        
        //创建索引输入流
        IndexReader indexReader= DirectoryReader.open(fsDirectory);
        IndexSearcher indexSearcher=new IndexSearcher(indexReader);
        
        //要查询的域
        String[] files={"title","origin","content"};
        //创建多域查询条件
        MultiFieldQueryParser parser=new MultiFieldQueryParser(files,new SmartChineseAnalyzer());
        Query query= parser.parse("巴西");
        //查询
        TopDocs docs = indexSearcher.search(query, 3);
        ScoreDoc[] scoreDocs=docs.scoreDocs;
        for (ScoreDoc scoreDoc:scoreDocs){
            //获取document对象属性
            //documentId
            int did = scoreDoc.doc;
            Document docObj = indexSearcher.doc(did);
            System.out.println("============"+did+"============");
            System.out.println(docObj.get("title"));
            System.out.println(docObj.get("origin"));
            System.out.println(docObj.get("content"));
            
        }
    }

查询结果:
在这里插入图片描述

布尔查询

布尔查询是使用最广泛的一种查询方式。可以组合其它所有的查询条件。可以将任何query对象作为布尔查询的子条件,从而决定最终的结果。比如在京东购买手机,可以选择品牌、价格区间、存储大小等组合条件进行查询。

由于前后代码都类似,这里只展示查询条件的创建过程:

 //要查询的域
  String[] files={"title","origin","content"};
    //创建多域查询条件1
    MultiFieldQueryParser parser=new MultiFieldQueryParser(files,new SmartChineseAnalyzer());
    Query query= parser.parse("疫苗");
    //创建词项查询条件2
    Term term=new Term("title","中国");
    Query query2= new TermQuery(term);
    
    //封装布尔查询子条件
    BooleanClause bc1=new BooleanClause(query,BooleanClause.Occur.MUST);
    BooleanClause bc2=new BooleanClause(query2,BooleanClause.Occur.MUST);
    
    //封装最终查询条件
    Query finalQuery=new BooleanQuery.Builder().add(bc1).add(bc2).build();

代码中,以下这两项的意思是,查询既满足query又满足query2的结果,也就是查询query和query2的交集:

BooleanClause bc1=new BooleanClause(query,BooleanClause.Occur.MUST);
BooleanClause bc2=new BooleanClause(query2,BooleanClause.Occur.MUST);

这里的各种组合关系,我们用图例说明:

取得query和query2查询子句的交集:
在这里插入图片描述
表示查询结果中不能包含MUST_NOT所对应的查询子句的检索结果:
在这里插入图片描述
MUST_NOT和MUST_NOT连用,没有任何搜索结果,查询无意义:
在这里插入图片描述
除此之外,还有SHOULD,有兴趣的可以继续深入拓展。

范围查询

可以对域属性中数字类型进行范围查询。
比如:查询文章点击率在10-70次的文章

 //范围查询 文章点击率在10-70次的文档
 Query rangeQuery=IntPoint.newRangeQuery("clickNum",10,70);

模糊查询

在title域中查找和“苗”类似的词语:

//模糊查询
Query fuzzyQuery=new FuzzyQuery(new Term("title","苗"));

通配查询

?代表任意一个字符。* 代表任意多个字符。

 //通配查询
Query wquery=new WildcardQuery(new Term("content","?国"));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章