我们可以使用luke工具来查询我们本地的索引存储信息。
查询的流程如下
在lucene中query有几种基本是查询类型。
词项查询 TermQuery
短语查询 PhraseQuery
布尔查询 BooleanQuery
正则查询 RegexpQuery
模糊查询 FuzzyQuery
前缀查询 PrefixQuery
通配符查询 WildcardQuery
范围查询 TermRangeQuery
这里的查询都是以词项为单位,每个查询的操作对象都是一个或多个词项。这里有一点需要注意的是短语查询查询对应的Field必须存储了位置信息, 不然在执行查询解析的时候会报错,提示没有该字段的位置信息。除了上面这些基本查询还有其他的类型。还有一种高级的查询类型就是QueryParse,它通过定义了一些规则就跟sql语法的规则似的,我们可以根据它的语法来使用查询,而不是自己去组装基础查询。
QueryParse需要我们指定一个默认的查询字段。当我们没有对值指定字段的时候就会使用默认字段。
语法结构= 字段名:值。存在对多个字段操作时使用空格隔开。在值这个位置我们可以使用上面的基本查询类型。比如name:*电脑,这个等于一个通配符查询,price:[200 TO 500}这个等于范围查询,[表示不包含边界,{包含边界,name:电脑~2,这个等于模糊查询中我们是指的模糊值为2,在模糊查询中,模糊值最大只能是2,它只有3个值可以选择,0,1,2. name:"台式电脑"~2,这个等于临近查询,会先对引号里面字符串分词,~表示分词后词项之间的跨度。name:电脑 price:[200 TO *] 这个等于一个词项查询和一个范围查询组成的布尔查询。注意中间是有空格的,这个表示或的操作。name:电脑 +price:[200 TO *]这个表示name包含电脑且价格在200以上的,是一个AND操作,我们也可以用AND ,这里是区分大小写的。name:电脑 +price:[200 TO *]=name:电脑 AND price:[200 TO *];name:电脑 NOT price:[200 TO *} 这个等于name包含电脑 切价格不在200以上的。
布尔操作符解释
AND = + ;AND是双目运算,+是单目,表示这个条件必须满足
OR = 不写 ;OR 跟sql中的OR是一个意思
NOT = - ;- 单目运算,也是必须满足的条件
还有一个^,我们在词项或短语中使用这个符号表示对其得分进行加权计算
简单查询使用代码
Analyzer analyzer = new IKAnalyzer(true);
QueryParser qp = new QueryParser("name", analyzer);
Query query = qp.parse("苹笔记本电脑~1");
// Query query = qp.parse("笔*脑");
// +单目运算 等同于 AND, !等同于- 表示否,相当于sql中的 and field!=。
// Query query = qp.parse("type:电脑 price:[2000 TO 9000}");
// Query query = qp.parse("type:游戏机 笔记本电脑 -price:[1000 TO 4000}");
// Query query = qp.parse("type:电脑 华为^3 +price:{2000 TO 9000}");
//范围查询,
// Query query = new TermRangeQuery("price", new BytesRef("2000"), new BytesRef("9000"), true, false);
//词项查询
// Query query = new TermQuery(new Term("name", "苹果"));
//模糊查询
// Query query = new FuzzyQuery(new Term("type", "电脑"), 2);
//短语查询
// Query query = new PhraseQuery(2,"type", "电脑","手机"); type字段我们没有存储字段信息,执行会报错
// Query query = new PhraseQuery(2,"name", "台式","电脑");
//前缀查询
// Query query = new PrefixQuery(new Term("name","笔"));
//通配符查询
// Query query = new WildcardQuery(new Term("name","???电脑"));
// Query query = new WildcardQuery(new Term("name","*电脑"));
//正则查询
// Query query = new RegexpQuery(new Term("name","台式|笔记本电脑"));
//不二查询
// Query query1 = new TermQuery(new Term("name", "台式"));
// Query query2 = new TermQuery(new Term("name", "电脑"));
// BooleanQuery.Builder booleanQueryBuilder = new BooleanQuery.Builder();
// booleanQueryBuilder.add(query1, Occur.SHOULD);
// booleanQueryBuilder.add(query2, Occur.MUST);
// BooleanQuery query = booleanQueryBuilder.build();
System.out.println(query.toString());
FSDirectory directory = FSDirectory.open((new File("d:/test/index2").toPath()));
DirectoryReader reader = DirectoryReader.open(directory);
IndexSearcher searcher = new IndexSearcher(reader);
// TopDocs docs = searcher.search(query, 10);
TopDocs docs = searcher.search(query, 10,new Sort(new SortField("price", Type.DOUBLE))); //按price排序
System.out.println(docs.scoreDocs.length);
for(ScoreDoc scoreDoc :docs.scoreDocs){
Document doc = searcher.doc(scoreDoc.doc);
System.out.println(scoreDoc.score);
System.out.println(doc.getBinaryValue("name").utf8ToString());
}
reader.close();
directory.close();