Edge n-грамм предложения и ключевое слово «начинается с» в Elasticsearch - PullRequest
1 голос
/ 29 февраля 2020

Я пытаюсь создать поисковую систему для продуктов питания на Elasticsearch, которая должна соответствовать следующим вариантам использования -

  1. Если пользователь ищет «coff», он должен вернуть все документы с фразу «кофе» в названии, и приоритет должен быть для продуктов, которые имеют «кофе» в начале своего названия.

  2. Если пользователь ищет «зеленый чай», то он следует отдавать приоритет документам, в которых есть фразы «зеленый чай», а не «зеленый» и «чай»

  3. Если в названии отсутствует фраза, то она также следует выполнить поиск в поле псевдонима.

Для управления первым случаем я использовал анализатор граничных n-грамм.

Отображение -

{
  "settings": {
    "index": {
      "analysis": {
        "filter": {},
        "analyzer": {
          "analyzer_keyword": {
            "tokenizer": "standard",
            "filter": "lowercase"
          },
          "edge_ngram_analyzer": {
            "filter": [
              "lowercase"
            ],
            "tokenizer": "edge_ngram_tokenizer"
          }
        },
        "tokenizer": {
          "edge_ngram_tokenizer": {
            "type": "edge_ngram",
            "min_gram": 2,
            "max_gram": 5,
            "token_chars": [
              "letter"
            ]
          }
        }
      }
    }
  },
  "mappings": {
    "doc": {
      "properties": {
        "alias": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        },
        "name": {
          "type": "text",
          "search_analyzer": "analyzer_keyword",
          "analyzer": "edge_ngram_analyzer",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        }
      }
    }
  }
}

Это поисковый запрос, который я использую, но он не совсем возвращает релевантные результаты поиска

{
  "query": {
    "multi_match": {
      "query": "coffee",
      "fields": ["name^2", "alias"]
    }
  }
}

Более 1500 продуктов с «кофе» в их имени, но приведенный выше запрос возвращает только 2

{
  "took": 745,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 8.657346,
    "hits": [
      {
        "_index": "food-master",
        "_type": "doc",
        "_id": "a9uzinABb4g7LgmgoI1I",
        "_score": 8.657346,
        "_source": {
          "id": 17463,
          "name": "Rotiboy, coffee bun",
          "alias": [
            "Mexican Coffee Bun (Rotiboy)",
            "Mexican coffee bun"
          ],
        }
      },
      {
        "_index": "food-master",
        "_type": "doc",
        "_id": "TNuzinABb4g7LgmgoFVI",
        "_score": 7.0164866,
        "_source": {
          "id": 1344,
          "name": "Coffee with sugar",
          "alias": [
            "Heart Friendly",
            "Coffee With Sugar",
            "Coffee With Milk and Sugar",
            "Gluten Free",
            "Hypertension Friendly"
          ],
        }
      }
    ]
  }
}

В отображении, если я удаляю ключевое слово analyzer_key, тогда оно возвращает релевантные результаты, но документы, начинающиеся с 'coffee', не имеют приоритета

{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1323,
    "max_score": 57.561867,
    "hits": [
      {
        "_index": "food-master-new",
        "_type": "doc",
        "_id": "nduzinABb4g7LgmgoINI",
        "_score": 57.561867,
        "_source": {
          "name": "Egg Coffee",
          "alias": [],
          "id": 12609
        }
      },
      {
        "_index": "food-master-new",
        "_type": "doc",
        "_id": "dNuzinABb4g7LgmgoFVI",
        "_score": 55.811295,
        "_source": {
          "name": "Coffee (Black)",
          "alias": [
            "Weight Loss",
            "Diabetes Friendly",
            "Gluten Free",
            "Lactose Free",
            "Heart Friendly",
            "Hypertension Friendly"
          ],
          "id": 1341
        }
      },
      {
        "_index": "food-master-new",
        "_type": "doc",
        "_id": "NduzinABb4g7LgmgoHxI",
        "_score": 54.303185,
        "_source": {
          "name": "Brewed Coffee",
          "alias": [
            "StarBucks"
          ],
          "id": 15679
        }
      },
      {
        "_index": "food-master-new",
        "_type": "doc",
        "_id": "ltuzinABb4g7LgmgoJJI",
        "_score": 54.303185,
        "_source": {
          "name": "Coffee - Masala",
          "alias": [],
          "id": 11329
        }
      },
      {
        "_index": "food-master-new",
        "_type": "doc",
        "_id": "oduzinABb4g7LgmgoGpI",
        "_score": 53.171227,
        "_source": {
          "name": "Coffee, German",
          "alias": [],
          "id": 12257
        }
      },
      {
        "_index": "food-master-new",
        "_type": "doc",
        "_id": "YNuzinABb4g7LgmgoFRI",
        "_score": 52.929176,
        "_source": {
          "name": "Soy Milk Coffee",
          "alias": [
            "Gluten Free",
            "Lactose Free",
            "Weight Loss",
            "Diabetes Friendly",
            "Heart Friendly",
            "Hypertension Friendly"
          ],
          "id": 978
        }
      },
      {
        "_index": "food-master-new",
        "_type": "doc",
        "_id": "8duzinABb4g7LgmgoFRI",
        "_score": 52.068523,
        "_source": {
          "name": "Cold Coffee (Soy Milk)",
          "alias": [
            "Soy Milk"
          ],
          "id": 1097
        }
      },
      {
        "_index": "food-master-new",
        "_type": "doc",
        "_id": "tNuzinABb4g7LgmgoF9I",
        "_score": 50.956154,
        "_source": {
          "name": "Coffee Frappe",
          "alias": [],
          "id": 3142
        }
      },
      {
        "_index": "food-master-new",
        "_type": "doc",
        "_id": "ZduzinABb4g7LgmgoF5I",
        "_score": 49.810112,
        "_source": {
          "name": "Big Apple Coffee",
          "alias": [],
          "id": 3130
        }
      },
      {
        "_index": "food-master-new",
        "_type": "doc",
        "_id": "eduzinABb4g7LgmgoHtI",
        "_score": 49.62197,
        "_source": {
          "name": "Mexican Coffee",
          "alias": [],
          "id": 13604
        }
      }
    ]
  }
}

Если я поменяю токенайзер на «ключевое слово» со «стандартного», то сталкиваюсь с той же проблемой, и он также разбивает фразы на отдельные слова - «зеленый чай» на «зеленый» 'and' tea '

Есть какие-нибудь предположения о том, что я могу ошибаться в отношении анализаторов? Я перепробовал все возможные комбинации, но встретить все 3 сценария ios с высокой точностью становится немного сложно.

...