我正在寻找一种在多种条件下过滤lucene索引的方法。为此我检查了两种不同的过滤搜索方法,它们都不适用于我:
使用BooleanQuery:
BooleanQuery query = new BooleanQuery();
String lower = "*";
String upper = "*";
for (String fieldName : keywordSourceFields) {
TermRangeQuery rangeQuery = TermRangeQuery.newStringRange(fieldName,
lower, upper, true, true);
query.add(rangeQuery, Occur.MUST);
}
TermRangeQuery rangeQuery = TermRangeQuery.newStringRange(keywordField,
lower, upper, true, true);
query.add(rangeQuery, Occur.MUST_NOT);
try {
TopDocs results = searcher.search(query, null,
maxNumDocs);
使用BooleanFilter:
BooleanFilter filter = new BooleanFilter();
String lower = "*";
String upper = "*";
for (String fieldName : keywordSourceFields) {
TermRangeFilter rangeFilter = TermRangeFilter.newStringRange(fieldName,
lower, upper, true, true);
filter.add(rangeFilter, Occur.MUST_NOT);
}
TermRangeFilter rangeFilter = TermRangeFilter.newStringRange(keywordField,
lower, upper, true, true);
filter.add(rangeFilter, Occur.MUST);
try {
TopDocs results = searcher.search(new MatchAllDocsQuery(), filter,
maxNumDocs);
我想知道选择的查询的哪一部分是错的?我正在寻找对于每个keywordSourceFields的文档,该字段具有一些值并且对于关键字字段也没有值。请指导我纠正相应的查询。
最好的问候。
答案 0 :(得分:2)
首先,为空字段索引默认值将是一个更多更好的主意。您在此处组合的每个子查询都必须枚举并搜索该字段的所有可用值,以确定不存在。可能它会很慢。
将*
作为查询字词传递不是构建开放式范围查询的有效方法。 null
是传递给它的正确值。传递null
作为较低的查询字词而includeLower
= true将导致异常(因为它没有意义)。
此外,TermRangeQuery
不允许两端为空,并将为此抛出异常。因此,查询的至少一端必须是定义的术语。您需要提出一个安全的上限或下限才能使用。
所以,你可以这样做:
Query subQuery = new TermRangeQuery("myField", "aaaaaaaaa", null, true, false);
或者使用过滤器:
Filter subFilter = new TermRangeFilter.More(myField, new BytesRef("aaaaaaaaa"));
当然,这有点笨拙,而且表现会很糟糕。您可以使用缓存过滤器来缓解这种情况,但使用默认值索引数据以在空字段的情况下进行搜索实际上就是您应该做的事情。当您以支持您想要进行的搜索的方式索引数据时,Lucene是最有用和最高效的。