ElasticSearch Query Игнорирование дополнительных условий поиска - PullRequest
0 голосов
/ 01 мая 2018

Я использую ElasticSearch для создания функции поиска по типу свободной формы для нескольких структурированных полей. Основные поля, по которым люди ищут: first_name, last_name и city.

Проблема : следующие два поиска David Salazar и David Salazar Denver возвращают те же результаты, в которых "Денвер", по-видимому, игнорируется.

Я предполагаю, что это проблема с моим запросом, но я застрял в том, как изменить его, чтобы получить то, что я ищу.

Вот запрос:

GET index_name/_search
{
  "query": {
    "multi_match": {
      "fields": [
        "first_name","middle_name", "last_name", "city", "county", "street"],
      "query": "David Salazar Denver",
      "type": "cross_fields",
      "use_dis_max": false
    }
  },
  "size": 10
}

Вот соответствующие части настройки индекса и отображения поля

{
  "index": {
    "aliases": {},
    "mappings": {
      "type": {
        "properties": {
          "city": {
            "type": "keyword"
          },
          "county": {
            "type": "keyword"
          },
          "first_name": {
            "type": "text",
            "analyzer": "synonym_autocomplete",
            "search_analyzer": "standard"
          },
          "last_name": {
            "type": "text",
            "analyzer": "autocomplete",
            "search_analyzer": "standard"
          },
          "middle_name": {
            "type": "text",
            "analyzer": "synonym_autocomplete",
            "search_analyzer": "standard"
          },
          "street": {
            "type": "text",
            "analyzer": "autocomplete",
            "search_analyzer": "standard"
          },
        }
      }
    },
    "settings": {
      "index": {
        [...]
        "analysis": {
          "filter": {
            "synonym": {
              "type": "synonym",
              "synonyms": [Long list of nicknames]
            },
            "autocomplete_filter": {
              "type": "edge_ngram",
              "min_gram": "2",
              "max_gram": "15"
            }
          },
          "analyzer": {
            "synonym_autocomplete": {
              "filter": [
                "standard", "lowercase", "synonym", "autocomplete_filter"],
              "type": "custom",
              "tokenizer": "standard"
            },
            "autocomplete": {
              "filter": ["standard","lowercase","autocomplete_filter"],
              "type": "custom",
              "tokenizer": "standard"
            }
          }
        },
        [...]
        }
      }
    }
  }
}

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

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

Итак, я создал новый индекс с кодом ниже и затем использовал reindex API для копирования данных в этот новый индекс

{
  "index": {
    "aliases": {},
    "mappings": {
      "type": {
        "properties": {
          "city": {
            "type": "keyword"
          },
          "county": {
            "type": "text",
            "analyzer": "synonym_autocomplete",
            "search_analyzer": "standard"
          },
          "first_name": {
            "type": "text",
            "analyzer": "synonym_autocomplete",
            "search_analyzer": "standard"
          },
          "last_name": {
            "type": "text",
            "analyzer": "autocomplete",
            "search_analyzer": "standard"
          },
          "middle_name": {
            "type": "text",
            "analyzer": "synonym_autocomplete",
            "search_analyzer": "standard"
          },
          "street": {
            "type": "text",
            "analyzer": "synonym_autocomplete",
            "search_analyzer": "standard"
          },
        }
      }
    },
    "settings": {
      "index": {
        [...]
        "analysis": {
          "filter": {
            "synonym": {
              "type": "synonym",
              "synonyms": [Long list of nicknames]
            },
            "autocomplete_filter": {
              "type": "edge_ngram",
              "min_gram": "2",
              "max_gram": "15"
            }
          },
          "analyzer": {
            "synonym_autocomplete": {
              "filter": [
                "standard", "lowercase", "synonym", "autocomplete_filter"],
              "type": "custom",
              "tokenizer": "standard"
            },
            "autocomplete": {
              "filter": ["standard","lowercase","autocomplete_filter"],
              "type": "custom",
              "tokenizer": "standard"
            }
          }
        },
        [...]
        }
      }
    }
  }
}
0 голосов
/ 01 мая 2018

Пожалуйста, ознакомьтесь с cross_fields документацией запроса. У вас есть параметр operator, который установлен на OR, если отсутствует. Это означает, что ваш текущий запрос ищет любой термин из "David Salazar Denver" в вашем списке полей ["first_name","middle_name", "last_name", "city", "county", "street"]. По сути, это означает, что документ будет возвращен из поиска только тогда, когда в любом из ваших полей будет найдено одно слово из поискового запроса.

...