9、索引库的查询三之:Lucene的多样化查询

1.4   Lucene的多样化查询
  • 在指定的项范围内搜索-TermRangeQuery类
  • 通过字符串搜索-PrefixQuery类
  • 组合查询-BooleanQuery类
  • 通过短语搜索-PhraseQuery类
  • 通配符查询-WildcardQuery类
  • 搜索类似项-FuzzyQuery类
  • 不匹配文档-MatchNoDocsQuery类
  • 解析查询表达式-QueryParser类
  • 多短语查询-MultiPhraseQuery类
好,我们分别对上面的类进行分析和例子的说明
TermRangeQuery类的说明
//TermRangeQuery 的查询方式 集合查询的方式
@Test
public void testTermRangeQuery() throws Exception {
    //以读的方式打开索引库
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //创建一个IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //创建一个IndexSearcher对象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    //创建一个查询对象
    //参数:1、要搜索的域 2、区间 以BytesRef中的值为开头,3、以BytesRef中的值为结尾, 4、是否包含  'a'  5、是否包含 'f'
    Query query = new TermRangeQuery("names",new BytesRef("a"),new BytesRef("f"),true,false);
    //执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查询结果总数量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document对象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("names"));
    }
    indexSearcher.getIndexReader().close();
}
PrefixQuery类的说明
//PrefixQuery 的查询方式 可表示为 匹配包含具有指定前缀的术语的文档的查询
@Test
public void testPrefixQuery () throws Exception {
    //以读的方式打开索引库
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //创建一个IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //创建一个IndexSearcher对象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    //创建一个查询对象
    //参数Term
    Query query = new PrefixQuery(new Term("name","web"));
    //执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查询结果总数量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document对象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("name"));
    }
    indexSearcher.getIndexReader().close();
}
BooleanQuery类的说明
//组合条件查询
@Test
public void testBooleanQuery() throws Exception {
    //以读的方式打开索引库
     Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //创建一个IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //创建一个IndexSearcher对象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    //创建查询条件
    Query query1 = new TermQuery(new Term("name", "apache"));
    Query query2 = new TermQuery(new Term("content", "lucene"));
    //创建一个查询对象 并添加值
    BooleanQuery query = new BooleanQuery.Builder().add(query1, BooleanClause.Occur.MUST).add(query2, BooleanClause.Occur.MUST_NOT).build();
   //执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查询结果总数量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document对象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("name"));
    }
    indexSearcher.getIndexReader().close();
}
MUST 相当于 and
SHOULD 相当于 or
MUST_NOT 相当于 not 非
FILTER 除MUST的值
PhraseQuery类的说明
//短语之间的查询
@Test
public void testPhraseQuery() throws Exception {
    //以读的方式打开索引库
     Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //创建一个IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //创建一个IndexSearcher对象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * 原文章内容:  软件开发程序员博客文章收藏网提供'lucene多条件查询'相关的博客文章收藏
     * 如果setSlop设置 小于2的值 则没有结果 ,因为 开发 程序员是两个不短句,只有大于等于2时,才成立 
     */
    //创建一个查询对象 并添加值
    PhraseQuery.Builder builder=new PhraseQuery.Builder().setSlop(3).add(new Term("text","软件开发")).add(new Term("text","文章"));
    PhraseQuery query=builder.build();
    //执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查询结果总数量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document对象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("text"));
    }
    indexSearcher.getIndexReader().close();
}// 看api上还有一些其他的说明,待研究
WildcardQuery类的说明
//模糊匹配查询
@Test
public void testWildcardQuery() throws Exception {
    //以读的方式打开索引库
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //创建一个IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //创建一个IndexSearcher对象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * 原文章内容:  软件开发程序员博客文章收藏网提供'lucene多条件查询'相关的博客文章收藏
     *   ?代表1个字符  *代表0个或N个字符
     */
    //创建一个查询对象 并添加值
    Query query=new WildcardQuery(new Term("text","软件*开发"));
    //执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查询结果总数量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document对象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("text"));
    }
    indexSearcher.getIndexReader().close();
}
FuzzyQuery类的说明
//模糊匹配查询 找相似的索引值
@Test
public void testFuzzyQuery() throws Exception {
    //以读的方式打开索引库
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //创建一个IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //创建一个IndexSearcher对象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * 原文章内容:  软件开发程序员博客文章收藏网提供'lucene多条件查询'相关的博客文章收藏
     * 注意FuzzyQuery是区分大小写的,同时默认的编辑距离的值是2
     * 注意两个Term之间的编辑距离必须小于两者中最小者的长度
     * 还可以设置第三个参数,第三个参数为前缀的长度 默认是0 
     */
    //创建一个查询对象 并添加值
    Query query=new FuzzyQuery(new Term("text","conerib"),1);
    //执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查询结果总数量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document对象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("text"));
    }
    indexSearcher.getIndexReader().close();
}
QueryParser类的说明 引用org.apache.lucene.queryparser.classic
//QueryParser匹配查询
@Test
public void testQueryParser() throws Exception {
    //以读的方式打开索引库
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //创建一个IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //创建一个IndexSearcher对象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * 原文章内容:  软件开发程序员博客文章收藏网提供'lucene多条件查询'相关的博客文章收藏
     */
    //创建查询
    //第一个参数是默认搜索域,如果查询时不指定要查询的域,
    //会到默认搜索域上进行搜索,如果指定了就按照指定的域进行搜索。
    //第二个参数:分析器对象
    QueryParser queryParser=new QueryParser("context",new MyWordAnalyzer());
    Query query=queryParser.parse("text:软件开发");
    //执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查询结果总数量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document对象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("text"));
    }
    indexSearcher.getIndexReader().close();
}
这里做一个补充:
1、基础的查询语法:
域名:关键词
Name:java
2、匹配所有文档:
*:*
3、范围查询语法:
:[最小值 TO最大值]
age:[0 TO 1000]
注意:TO要大写 
lucene中范围查询不支持数值类型,如果要查询数值类型的范围还需要使用IntPoint等方式
仅适用于字符串类型。此语法在solr中支持数值类型。
4、组合条件查询
+name:apache -name:lucene
+:代表必须满足此条件,相当于     Occur.MUST
-:必须不满足此条件Occur.MUST_NOT
name:apache name:lucene
什么都没有:应该满足此条件。Occur.SHOULD
Occur.MUST 查询条件必须满足,相当于and+(加号)
Occur.SHOULD 查询条件可选,相当于or空(不用符号)
Occur.MUST_NOT 查询条件不能满足,相当于not非-(减号)
 
查询语法的第二种写法:
+name:apache +name:lucenename:apache AND name:lucene
name:apache name:lucenename:apache OR name:lucene
name:apache -name:lucenename:apache NOT name:lucene
MultiFieldQueryParser 类
//MultiFieldQueryParser 类
@Test
public void  testMultiFieldQueryParser() throws Exception {
    //以读的方式打开索引库
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //创建一个IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //创建一个IndexSearcher对象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * 原文章内容:  软件开发程序员博客文章收藏网提供'lucene多条件查询'相关的博客文章收藏
     */
    //创建查询
    //第一个参数是默认搜索域,如果查询时不指定要查询的域,
    //会到默认搜索域上进行搜索,如果指定了就按照指定的域进行搜索。
    //第二个参数:分析器对象
    //默认搜索域  配置多个域
    String[] fields = {"text", "content"};
    MultiFieldQueryParser queryParser=new MultiFieldQueryParser(fields,new MyWordAnalyzer());
    Query query=queryParser.parse("软件开发");
    //执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查询结果总数量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document对象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("text"));
    }
    indexSearcher.getIndexReader().close();
}
多短语查询-MultiPhraseQuery类
//MultiFieldQueryParser 类
@Test
public void  testMultiPhraseQuery() throws Exception {
    //以读的方式打开索引库
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //创建一个IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //创建一个IndexSearcher对象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * 原文章内容:  软件开发程序员博客文章收藏网提供'lucene多条件查询'相关的博客文章收藏
     */
    Term[] terms = new Term[]{new Term("text", "lucene"),new Term("text", "收藏网")};
    Term term=new Term("text", "查询");
    //多个add之间认为是OR操作,即(lucene 和收藏网 )与查询之间的slop值,满足多个 Term[] 的参数
    MultiPhraseQuery query = new MultiPhraseQuery.Builder().add(terms).add(term).setSlop(2).build();
    //执行查询
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查询结果总数量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document对象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("text"));
    }
    indexSearcher.getIndexReader().close();
}

下面是小编的微信转帐二维码,小编再次谢谢读者的支持,小编会更努力的

----请看下方↓↓↓↓↓↓↓

百度搜索 Drools从入门到精通:可下载开源全套Drools教程

深度Drools教程不段更新中:


更多Drools实战陆续发布中………

扫描下方二维码关注公众号 ↓↓↓↓↓↓↓↓↓↓



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值