全文搜索之lucence入门(三) 查询索引

我们可以使用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();

猜你喜欢

转载自blog.csdn.net/u012477338/article/details/80513044