Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带通配符的Lucene短语查询_Lucene_Query Performance_Phrase - Fatal编程技术网

带通配符的Lucene短语查询

带通配符的Lucene短语查询,lucene,query-performance,phrase,Lucene,Query Performance,Phrase,我提出了一个解决方案,使用以下代码以编程方式创建查询来搜索带有通配符的短语: public static Query createPhraseQuery(String[] phraseWords, String field) { SpanQuery[] queryParts = new SpanQuery[phraseWords.length]; for (int i = 0; i < phraseWords.length; i++) { WildcardQ

我提出了一个解决方案,使用以下代码以编程方式创建查询来搜索带有通配符的短语:

public static Query createPhraseQuery(String[] phraseWords, String field) {
    SpanQuery[] queryParts = new SpanQuery[phraseWords.length];
    for (int i = 0; i < phraseWords.length; i++) {
        WildcardQuery wildQuery = new WildcardQuery(new Term(field, phraseWords[i]));
        queryParts[i] = new SpanMultiTermQueryWrapper<WildcardQuery>(wildQuery);
    }
    return new SpanNearQuery(queryParts,       //words
                             0,                //max distance
                             true              //exact order
    );
}
产出:

spanNear([SpanMultiTermQueryWrapper(text:foo*), SpanMultiTermQueryWrapper(text:b*r)], 0, true)
这非常有效,在大多数情况下都足够快。例如,如果我创建这样的查询并使用它进行搜索,它将输出所需的结果,例如:

Sentence with foo bar.
Foolies beer drinkers.
...
而不是像:

Bar fooes.
Foo has bar.
我已经提到,在大多数情况下,查询的工作速度足够快。目前我有一个索引,大小为aprox。200GB,平均搜索时间在0.1到3秒之间。这取决于许多因素,如缓存、匹配短语中单个单词的文档子集的大小,因为lucene将在已建立的术语之间执行集合交集

例如: 假设我想查询短语“an*karenjin*”(我将其分为[“an*”,“karenjin*”],然后使用createPhraseQuery方法创建查询),我想它匹配包含以下内容的句子:“ana karenjina”,“ani karenjinoj”,“ane karenjine”。。。(由于克罗地亚语语法的不同情况)

这个查询非常慢,我没有等待足够长的时间来获得结果(超过1小时),有时会导致超出GC开销限制的异常。 这种行为是意料之中的,因为“an*”本身匹配大量文档。我知道我可以查询“an?karanjin*”,给出者的结果在30-40秒(更快,但仍然很慢)

这就是我困惑的地方。 如果我只查询“karenjin*”,它会在1秒内给出结果。因此,我尝试查询“an*karenjin*”并使用通配符查询和QueryWrapperFilter使用过滤器“karenjin*”。而且它仍然是不可接受的慢(我在它返回任何东西之前杀死了进程)

文档表明,过滤器减少了查询的搜索空间。所以我尝试使用过滤器:

Filter filter = new QueryWrapperFilter(new WildcardQuery(new Term("text", "karanjin*")));
和查询:

Query query = createPhraseQuery(new String[]{"an*", "karenjin*"}, "text");
然后进行搜索(在几个预热查询之后):

好的,我的问题是什么?

为什么是查询:

 Query query = new WildcardQuery(new Term("text", "karanjin*"));

是的,通配符可能会影响性能,特别是当它们匹配很多术语时,但您所描述的似乎确实令人惊讶。很难说清楚为什么会发生这种情况,但这只是一次尝试

我假设:

Query Query=新的通配符查询(新术语(“文本”、“an*”));
就其自身而言,正如所描述的,它的表现非常糟糕。由于您要查找的通配符都是前缀样式的查询,因此最好使用
PrefixQuery

Query Query=新前缀Query(新术语(“文本”、“安”));
虽然我不认为这会有什么不同,如果有的话。改变重写方法可能会使情况有所不同。您可以尝试限制将查询重写为以下内容的
术语的数量:

Query Query=新前缀Query(新术语(“文本”、“安”));
//或
//查询查询=新的通配符查询(新术语(“文本”、“an*”));
setRewriteMethod(新的MultiTermQuery.RewriteMethod.TopTermsRewrite(10));

感谢您的建议,我将尝试限制条款的数量,并查看其性能。我希望它会快得多。但结果可能不完整。这是时间和结果之间的折衷。我会试试看。根据《Lucene in action》一书,如果通配符以*结尾,则会在内部识别并优化为PrefixQuery,如果没有通配符,则会优化为TermQuery。我相信这是正确的,但我更希望这种逻辑存在于解析中,而我在那里没有看到它。不过,这可能是重写本身的一部分。在Lucene的当前版本中,PrefixQuery和WildcardQuery都扩展了AutomatonQuery,它们生成的自动机是相同的,因此选择其中一个没有明显的好处。
Sort sort = new Sort(new SortField("insertTime", SortField.Type.STRING, true));
TopDocs docs = searcher.search(query, filter, 100, sort);
 Query query = new WildcardQuery(new Term("text", "karanjin*"));