lucene搜索之高级查询
Posted jiang_xiang_it
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lucene搜索之高级查询相关的知识,希望对你有一定的参考价值。
- 使用Query子类查询
MatchAllDocsQuery
TermQuery
NumericRangeQuery
BooleanQuery
- 使用QueryParser
QueryParser
MulitFieldQueryParser
先抽取公共代码
private void dosearch(Query query) throws IOException { //给出索引库位置 FSDirectory directory = FSDirectory.open(new File("E:\\upload\\lucene")); //创建indexReader DirectoryReader reader = IndexReader.open(directory); //创建search对象 IndexSearcher searcher = new IndexSearcher(reader); TopDocs topDocs = searcher.search(query, 10); System.out.println(query); ScoreDoc[] ScoreDocs = topDocs.scoreDocs; System.out.println(topDocs.totalHits); //查询命中的条数 for (ScoreDoc scoreDoc:ScoreDocs) { int id = scoreDoc.doc;//文档的id Document doc = searcher.doc(id);//获取doc对象 System.out.println(doc.get("id")); System.out.println(doc.get("name")); // System.out.println(doc.get("price")); // System.out.println(doc.get("pic")); // System.out.print(doc.get("description")); } reader.close(); }
第一个MatchAllDoceQuery,是全匹配,匹配的语法是 *:*
@Test public void doMatchAllDocsQuery() throws Exception {//创建query对象 MatchAllDocsQuery query = new MatchAllDocsQuery(); dosearch(query); }
第二个 是 TermQuery,是精确匹配, 下面匹配的语法是: description:项目
TermQuery termQuery = new TermQuery(new Term("description","项目"));
dosearch(query);
第三个NumericRangeQuery,数字的匹配,表示区间
第一个参数:域的名称
第二个参数:最小值
第三个参数:最大值
第四个参数:是否包含最小值
第五个参数:是否包含最大值
域名+“:”+[数值 TO 数值] 表示数值范围,并且包括数值。如果不包括数值 用"{}"
比如:
price:[55.0 TO 70.0] 等同于 55=< price <=70
price:{55.0 TO 70.0] 等同于 55 < price <=70
@Test public void doNumericRangeQuery() throws Exception {//创建query对象 NumericRangeQuery price =NumericRangeQuery.newFloatRange("price", 55F, 56F, true, true); dosearch(price); }
第四个是BooleanQuery,多条件查询
1、MUST和MUST表示“与”的关系,即“交集”。
2、MUST和MUST_NOT前者包含后者不包含。
3、MUST_NOT和MUST_NOT没意义
4、SHOULD与MUST表示MUST,SHOULD失去意义;
5、SHOUlD与MUST_NOT相当于MUST与MUST_NOT。
6、SHOULD与SHOULD表示“或”的概念。
@Test public void doBooleanQuery() throws Exception {//创建query对象 BooleanQuery query = new BooleanQuery(); TermQuery query1 = new TermQuery(new Term("name","java")); NumericRangeQuery<Float> query2 = NumericRangeQuery.newFloatRange("price", 55F, 56F, true, true); query.add(query1, BooleanClause.Occur.SHOULD); query.add(query2, BooleanClause.Occur.SHOULD); dosearch(query); }
query的子类不需要指定分词器,而且不能指定查询的语法
queryparser 需要指定分词器 ,而且可以指定查询的语法
第五个queryParse
TermQuery 是全匹配搜索,如果要搜索一段文字,需要整体匹配才行,如果要搜索包含在这段文字中的词,需要对这段文字进行分词。才能进行搜索。queryparser就可以指定一个分词器,再进行解析,进行查询。
@Test public void doQueryParse() throws Exception { //创建query对象 Analyzer analyzer=new IKAnalyzer(); QueryParser parser = new QueryParser("name",analyzer); // Query query = parser.parse("*:*"); // Query query = parser.parse("lucene java"); // Query query = parser.parse("name:java AND name:编程"); Query query = parser.parse("+name:java +name:编程"); dosearch(query); }
第六个MultiFieldQueryParser,可进行多个域匹配
@Test public void doMultiFieldQueryParser() throws Exception { Analyzer i=new IKAnalyzer(); String[] fields={"name","description"}; MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields, i); Query query = queryParser.parse("lucene"); dosearch(query); }
数值范围类的查询语法,不支持在queryparser中查询。语法是没有错误的。在solr中可以查询出来。
组合条件查询
Occur.MUST 查询条件必须满足,相当于and |
+(加号) |
Occur.SHOULD 查询条件可选,相当于or
|
空(不用符号) |
Occur.MUST_NOT 查询条件不能满足,相当于not非 |
-(减号) |
1)+条件1 +条件2:两个条件之间是并且的关系and
例如:+filename:apache +content:apache
2)+条件1 条件2:必须满足第一个条件,忽略第二个条件
例如:+filename:apache content:apache
3)条件1 条件2:两个条件满足其一即可。
例如:filename:apache content:apache
4)-条件1 条件2:必须不满足条件1,要满足条件2
例如:-filename:apache content:apache
第二种写法:
条件1 AND 条件2
条件1 OR 条件2
条件1 NOT 条件2
注意:
Search方法需要指定匹配记录数量n:indexSearcher.search(query, n)
TopDocs.totalHits:是匹配索引库中所有记录的数量
TopDocs.scoreDocs:匹配相关度高的前边记录数组,scoreDocs的长度小于等于search方法指定的参数n
以上是关于lucene搜索之高级查询的主要内容,如果未能解决你的问题,请参考以下文章
(VIP-朝夕教育)2021-06-06 .NET高级班 39-搜索引擎Lucene的使用
搜索引擎系列六:Lucene搜索详解(Lucene搜索流程详解搜索核心API详解基本查询详解QueryParser详解)