Почему фонетический поиск намного медленнее, чем обычный запрос на совпадение

Резюме: я пытаюсь понять, почему два запроса, которые кажутся очень похожими по сложности, сильно отличаются по скорости выполнения.

Я использую 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)",

и это занимает около 200 мсек для индекса с ~15 миллионами записей.

Так как он, казалось, преобразовал мой единственный поисковый термин в 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, эти два запроса выглядят очень похожими по сложности (поиск по 5 терминам с оператором OR), и я не могу понять, почему один намного медленнее, чем другой.

Любое понимание будет высоко ценится!

Заранее спасибо!

С уважением Марио

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
    }
  }
}

1 ответ

Решение

Я бы сказал, что довольно ясно, в чем разница между этими двумя - rewrite процесс ака расширение срока mario к синонимам, которые существуют. Этот процесс в основном требует от вас обработки через SynonymGraphFilter, который, я считаю, считывает данные о синонимах с диска, что замедляет работу.

В случае логического запроса совпадение проходит через другую цепочку анализатора (что, я думаю, является фонетическим, но без синонимов)

Другие вопросы по тегам