摘要:我试图理解为什么两个在复杂性上看起来非常相似的查询在执行速度上却大不相同。
我正在使用 Elastic Search 6.4,并且我有一个我想在其上使用语音查询的名称字段。
例如,我分析了搜索词“Mario”的语音查询,发现背景中的 Lucene 正在将其作为 SynonymQuery 执行:
"type": "SynonymQuery",
"description": "Synonym(person.firstName.phonetic:mYrio person.firstName.phonetic:mari person.firstName.phonetic:mario person.firstName.phonetic:mori person.firstName.phonetic:morio)",
对一个拥有约 1500 万条记录的索引执行此操作大约需要 200 毫秒。
由于它似乎将我的单个搜索词转换为 5 个同义词,我想“好吧,如果我搜索相同的 5 个不带语音的词怎么办?它会同样慢吗?” 或者换句话说“不是语音部分使它变慢,而是它必须搜索几个同义词的事实?”
但事实证明,如果我在没有拼音的字段中查询“mario mYrio mari mori morio”,它将产生一个 BooleanQuery(每个同义词作为子项查询一个术语):
"type": "BooleanQuery",
"description": "person.firstName:mario person.firstName:mYrio person.firstName:mari person.firstName:mori person.firstName:morio",
只需要 1/10 的时间。请注意:我知道并理解这两个查询给出不同的结果。我不想用第二个查询来模拟语音搜索。我只是想看看它是否也会很慢,因为它似乎是一个类似复杂性的查询。
对于像我这样最近才开始使用 Elastic Search 的人来说,这两个查询在复杂性上看起来非常相似(使用 OR 运算符搜索 5 个术语),我不明白为什么一个比另一个慢得多。
任何见解将不胜感激!
提前致谢!
问候马里奥
PS:我意识到如果我包括我在这个例子中使用的两个查询可能会有所帮助:
第一个查询(语音):
{
"profile": true,
"size": 1,
"timeout": "10s",
"query": {
"bool": {
"should": [
{
"match": {
"person.firstName.phonetic": {
"query": "mario",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
}
}
第二个查询(非语音):
{
"profile": true,
"size": 1,
"timeout": "10s",
"query": {
"bool": {
"should": [
{
"match": {
"person.firstName": {
"query": "mario myrio mari mori morio",
"operator": "OR",
"fuzziness": "0",
"prefix_length": 3,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
}
}