Lucene 使用多个过滤器过滤索引文档
Lucene filtering indexed documents with multiple filters
我正在寻找一种方法来过滤具有多个条件的 lucene 索引。为此,我检查了两种不同的过滤搜索方法,none 对我有用:
使用布尔查询:
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 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 的文档,该字段具有一些值并且也没有关键字字段的值。请指导我更正相应的查询。
此致。
首先,很多更好的想法是为空字段索引默认值。您在此处组合的每个子查询都必须枚举和搜索该字段的所有可用值以确定 none 是否存在。可能会很慢。
将 *
作为查询词传入不是构建开放式范围查询的有效方法。 null
是为此传递的正确值。将 null
作为较低的查询词传递并且 includeLower
= true 将导致异常(因为它没有意义)。
此外,TermRangeQuery
不允许两端为空,并且会抛出异常。因此,查询的至少一端必须是已定义的术语。您需要提出一个安全上限或下限才能使用。
因此,您可以执行以下操作:
Query subQuery = new TermRangeQuery("myField", "aaaaaaaaa", null, true, false);
或者使用过滤器你可以:
Filter subFilter = new TermRangeFilter.More(myField, new BytesRef("aaaaaaaaa"));
当然,这有点老套,而且性能会很糟糕。您可以使用缓存过滤器来缓解这种情况,但是在空字段的情况下使用默认值索引您的数据以进行搜索确实是您应该做的。当您以支持您想要执行的搜索类型的方式为数据编制索引时,Lucene 是最有用和最高效的。
我正在寻找一种方法来过滤具有多个条件的 lucene 索引。为此,我检查了两种不同的过滤搜索方法,none 对我有用:
使用布尔查询:
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 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 的文档,该字段具有一些值并且也没有关键字字段的值。请指导我更正相应的查询。
此致。
首先,很多更好的想法是为空字段索引默认值。您在此处组合的每个子查询都必须枚举和搜索该字段的所有可用值以确定 none 是否存在。可能会很慢。
将 *
作为查询词传入不是构建开放式范围查询的有效方法。 null
是为此传递的正确值。将 null
作为较低的查询词传递并且 includeLower
= true 将导致异常(因为它没有意义)。
此外,TermRangeQuery
不允许两端为空,并且会抛出异常。因此,查询的至少一端必须是已定义的术语。您需要提出一个安全上限或下限才能使用。
因此,您可以执行以下操作:
Query subQuery = new TermRangeQuery("myField", "aaaaaaaaa", null, true, false);
或者使用过滤器你可以:
Filter subFilter = new TermRangeFilter.More(myField, new BytesRef("aaaaaaaaa"));
当然,这有点老套,而且性能会很糟糕。您可以使用缓存过滤器来缓解这种情况,但是在空字段的情况下使用默认值索引您的数据以进行搜索确实是您应该做的。当您以支持您想要执行的搜索类型的方式为数据编制索引时,Lucene 是最有用和最高效的。