ElasticSearch - частичные совпадения по нескольким полям - PullRequest
0 голосов
/ 20 декабря 2018

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

{
    "document-id": "Patient1",
    "document-type": "patients",
    "firstName": "Benjamin",
    "lastName": "Carlton",
    "medicalRecordNumber": "111-222-3333"
}
{
    "document-id": "Patient2",
    "document-type": "patients",
    "firstName": "Carly",
    "lastName": "Benson",
    "medicalRecordNumber": "111-222-3334"
}
{
    "document-id": "Patient3",
    "document-type": "patients",
    "firstName": "Jason",
    "lastName": "Benson",
    "medicalRecordNumber": "111-222-3335"
}

Я хотел бы разработать анализатор и поисковый запрос таким образом, чтобы искать:

  • "ben" соответствийвсе три (это просто)
  • совпадения "ben carl" # 1 и # 2
  • совпадения "carl ben" также соответствуют совпадениям # 1 и # 2
  • "benj carl"только # 1 (не так естественно, как я думал ранее, учитывая то, как работают токенайзеры ngram)
  • "carlt ben" соответствует только # 2 (тоже самое)
  • "benj carlt "не будет совпадений
  • только совпадения" 111-222-3334 "# 2

Я чувствую, что я близко, используя следующий анализатор:

{
    "settings": {
        "analysis": {
            "tokenizer": {
                "partialMatchTokenizer": {
                    "type": "edge_ngram",
                    "min_gram": 2,
                    "max_gram": 10
                }
            },
            "analyzer": {
                "partialMatchAnalyzer": {
                    "type": "custom",
                    "tokenizer": "partialMatchTokenizer",
                    "char_filter": [],
                    "filter": [
                        "lowercase"
                    ]
                }
            }
        }
    },
    "mappings": {
        "_doc": {
            "properties": {
                "lastName": {
                    "type": "text",
                    "analyzer": "partialMatchAnalyzer"
                },
                "firstName": {
                    "type": "text",
                    "analyzer": "partialMatchAnalyzer"
                }
            }
        }
    }
}

И следующий запрос:

{
    "query": {
        "multi_match": {
            "query": "carlt ben",
            "type": "cross_fields",
            "fields": [
                "firstName",
                "lastName",
                "medicalRecordNumber"
            ],
            "operator": "or"
        }
    }
}

Но это не совсем так.«Или» кажется слишком допустимым;«и» кажется слишком ограничительным.И иногда совпадение по n-граммам дает неожиданные результаты.Например, приведенный выше запрос («carlt ben») соответствует и # 1, и # 2 (т. Е. «Carlt» соответствует «Carly», предположительно, потому что «carl» n-грамм соответствует).Также, как ни странно, «carlt ben» и «ben carlt» предоставляют два разных набора результатов (# 1 & # 2 против # 1 & # 2 & # 3).

Любые идеи о том, как мне нужно изменитьсямой анализатор и / или мой запрос, чтобы получить результаты, которые я описал выше?

...