请您先登录,才能继续操作

[lucene] 请教查询时如何限定某些条件?

TonyLian 2010-01-11
比如在做索引的时候,给每一个Document就加了一个Field,用于标识这一条内容的性质。比如:news / sport / game / it / 。。。

当我只想在某一种或某几种范围内查询时,该如何弄 Query ?
比如,我只想在 news 和 sport 的范围内查找“足球 实况”
这时候查询结果都是体育实况转播相关的内容,而没有关于《实况足球》这款游戏的内容。

谢谢了。
TonyLian 2010-01-18
我是想实现类似 SQL文中
where type in ('txt', 'pdf')
and owner in ('tom','jerry')
这样限定条件。

苦于提问了没人回答,只能自己苦讯,看了很多资料后,结合几个资料中的知识,终于写出来了:
TonyLian 2010-01-18
String[] fields = {Constants.FEILD_NAME_TITLE, Constants.FEILD_NAME_CONTENTS};        
Query query = MultiFieldQueryParser.parse(Version.LUCENE_CURRENT, new String[]{q,q}, fields, analyzer);

// 过滤器
Filter typeFilter = new FieldCacheTermsFilter(Constants.FEILD_NAME_FILETYPE, types);
Filter ownerFilter = new FieldCacheTermsFilter(Constants.FEILD_NAME_OWNER, owners);
// 把过滤器应用于Query
query = new FilteredQuery(query, typeFilter);
query = new FilteredQuery(query, ownerFilter);
	        
//搜索相似度最高的count条记录
TopDocs topDocs = isearcher.search(query, count);
luckaway 2010-01-18
TermQuery不能满足你的需求

Filter是不会利用倒排索引这一特性的,说实话,你这种情况用Filter来实现,应该会遍历所有的文档,虽然排序结果也会缓存的,但是效率肯定远远不及TermQuery方式来查询。
TonyLian 2010-01-18
luckaway 写道
TermQuery不能满足你的需求

Filter是不会利用倒排索引这一特性的,说实话,你这种情况用Filter来实现,应该会遍历所有的文档,虽然排序结果也会缓存的,但是效率肯定远远不及TermQuery方式来查询。


谢谢指导,我只是试验效果出来了,确实没有考虑性能问题。
主要是苦于没有类似的例子,看了LS的指点,去研究一下TermQuery
TonyLian 2010-01-18
请问是这样吗?

String[] fields = {"title", "contents"};        
Query query = MultiFieldQueryParser.parse(Version.LUCENE_CURRENT, new String[]{q,q}, fields, analyzer);

Query query1 = new TermQuery(new Term(“Type“, "txt")); 
Query query2 = new TermQuery(new Term(”Types”, "pdf")); 
Query query3 = new TermQuery(new Term(“owner“, "tom")); 
Query query4 = new TermQuery(new Term("owner", "jerry")); 
	        
BooleanQuery bqType = new BooleanQuery();
bqType.add(query1, BooleanClause.Occur.SHOULD);
bqType.add(query2, BooleanClause.Occur.SHOULD);
	        
BooleanQuery bqOwner = new BooleanQuery();
bqOwner.add(query3, BooleanClause.Occur.SHOULD);
bqOwner.add(query4, BooleanClause.Occur.SHOULD);
	        
BooleanQuery bqTotal = new BooleanQuery();
bqTotal.add(bqType, BooleanClause.Occur.MUST);
bqTotal.add(bqOwner, BooleanClause.Occur.MUST);
bqTotal.add(query, BooleanClause.Occur.MUST);
	        
//搜索相似度最高的count条记录
TopDocs topDocs = isearcher.search(bqTotal, count);
luckaway 2010-01-18
恩,这样可以!
TonyLian 2010-01-18
luckaway 写道
恩,这样可以!


非常感谢!

另外,这两种的性能能差多少呀?
luckaway 2010-01-18
性能差多少,肯定没有一个具体的值!

Filter是遍历所有的文档(可能lucene做了些技巧,不会遍历所有的文档),过滤出符合条件的文档。

TermQuery是直接通过分类的值找到对应的文档Id的集合。


如果的分类非常多,上上百万、甚至上千万个分类,那可能Filter效率反而会比TermQuery要高。









TonyLian 2010-01-19
可以这样理解吗?用SQL查询做比喻

TermQuery就是Where条件,直接在查询时做限制

Filter是对查询出的结果集再做遍历、筛选
Global site tag (gtag.js) - Google Analytics