Как сделать поиск elasti c более гибким? - PullRequest
0 голосов
/ 12 февраля 2020

Я сейчас использую этот запрос DSLasticsearch:

{
    "_source": [
        "title",
        "bench",
        "id_",
        "court",
        "date"
    ],
    "size": 15,
    "from": 0,
    "query": {
        "bool": {
            "must": {
                "multi_match": {
                    "query": "i r coelho",
                    "fields": [
                        "title",
                        "content"
                    ]
                }
            },
            "filter": [],
            "should": {
                "multi_match": {
                    "query": "i r coelho",
                    "fields": [
                        "title.standard^16",
                        "content.standard"
                    ]
                }
            }
        }
    },
    "highlight": {
        "pre_tags": [
            "<tag1>"
        ],
        "post_tags": [
            "</tag1>"
        ],
        "fields": {
            "content": {}
        }
    }
}

Вот что происходит. Если я ищу I.r coelho, он возвращает правильные результаты. Но, если я ищу I R coelho (без точки), он возвращает другой результат. Как я могу предотвратить это? Я хочу, чтобы поиск вел себя так же, даже если есть дополнительные точки, пробелы, запятые и т. Д. c.

Отображение

{
    "courts_2": {
        "mappings": {
            "properties": {
                "author": {
                    "type": "text",
                    "analyzer": "my_analyzer"
                },
                "bench": {
                    "type": "text",
                    "analyzer": "my_analyzer"
                },
                "citation": {
                    "type": "text"
                },
                "content": {
                    "type": "text",
                    "fields": {
                        "standard": {
                            "type": "text"
                        }
                    },
                    "analyzer": "my_analyzer"
                },
                "court": {
                    "type": "text"
                },
                "date": {
                    "type": "text"
                },
                "id_": {
                    "type": "text"
                },
                "title": {
                    "type": "text",
                    "fields": {
                        "standard": {
                            "type": "text"
                        }
                    },
                    "analyzer": "my_analyzer"
                },
                "verdict": {
                    "type": "text"
                }
            }
        }
    }
}

Настройки:

{
    "courts_2": {
        "settings": {
            "index": {
                "highlight": {
                    "max_analyzed_offset": "19000000"
                },
                "number_of_shards": "5",
                "provided_name": "courts_2",
                "creation_date": "1581094116992",
                "analysis": {
                    "filter": {
                        "my_metaphone": {
                            "replace": "true",
                            "type": "phonetic",
                            "encoder": "metaphone"
                        }
                    },
                    "analyzer": {
                        "my_analyzer": {
                            "filter": [
                                "lowercase",
                                "my_metaphone"
                            ],
                            "tokenizer": "standard"
                        }
                    }
                },
                "number_of_replicas": "1",
                "uuid": "MZSecLIVQy6jiI6YmqOGLg",
                "version": {
                    "created": "7010199"
                }
            }
        }
    }
}

РЕДАКТИРОВАТЬ Вот результаты для I.R coelho из my analyzer - { "tokens": [ { "token": "IR", "start_offset": 0, "end_offset": 3, "type": "<ALPHANUM>", "position": 0 }, { "token": "KLH", "start_offset": 4, "end_offset": 10, "type": "<ALPHANUM>", "position": 1 } ] }

Стандартный анализатор:

{
    "tokens": [
        {
            "token": "i.r",
            "start_offset": 0,
            "end_offset": 3,
            "type": "<ALPHANUM>",
            "position": 0
        },
        {
            "token": "coelho",
            "start_offset": 4,
            "end_offset": 10,
            "type": "<ALPHANUM>",
            "position": 1
        }
    ]
}

1 Ответ

1 голос
/ 14 февраля 2020

причина, по которой у вас другое поведение при поиске I.r coelho и I R coelho, заключается в том, что вы используете разные анализаторы в одних и тех же полях, т. Е. my_analyzer для title и content (must блок) и standard (по умолчанию) для title.standard и content.standard (should блок).

Два анализатора генерируют разные токены, определяя, таким образом, разные оценки при поиске I.r coelho (например, 2 токена со стандартным анализатором) или I R coelho (например, 3 токена со стандартным анализатором ). Вы можете проверить поведение ваших анализаторов с помощью analyze API (см. Документацию Elasti c ).

Вы должны решить, является ли это вашим желаемым поведением.

Обновления (после запрошенных разъяснений от OP)

Результаты запроса _analyze подтвердили гипотезу: два анализатора привели к различному вкладу в баллы, и, следовательно, к различным результатам в зависимости от того, содержит ли ваш запрос символьные символы или нет.

Если вы не хотите, чтобы на результаты вашего запроса влияли такие символы, как точки или прописные / строчные буквы, вам нужно будет пересмотреть, какие анализаторы вы хотите применить. Те, что используются в настоящее время, никогда не удовлетворят вашим требованиям. Если я правильно понял ваши требования, то встроенный анализатор simple должен быть правильным для вашего случая использования.

В двух словах: (1) вам следует подумать о замене встроенного анализатора standard на simple, (2) вам следует решить, хотите ли вы, чтобы ваш запрос применял разные оценки к совпадения, основанные на различных анализаторах (т. е. пользовательский phoneti c для значений полей title и content и один simple для соответствующих подполей).

...