Точный поиск с ElasticSearch 7.x - PullRequest
0 голосов
/ 28 января 2020

Я пытаюсь найти точный поиск URL с помощью ElasticSearch ("@astic /asticsearch": "^ 7.5.0"). Я настроил свое сопоставление так:

const schema = {
      userId: {
        type: "keyword"
      },
      url: {
        type: "keyword",
        index: false,
        analyzer: 'keyword'
      },
      pageTitle: {
        type: 'text',
      },
      pageText: {
        type: 'text',
      }
    };

    await client.indices.putMapping({
      index,
      type,
      include_type_name: true,
      body: {
        properties: schema
      }
    })

Я пробовал разные запросы, и они выглядят так:

body: {
        query: {
          bool: {
            must: {
              match: {
                query: 'test stack',
                analyzer: 'keyword',  
              }
            }
          }
        }
      }

Или вторая попытка:

body: {
        query: {
          constant_score: {
            filter: {
              bool: {
                must: {
                  term: {
                    url: 'test stack'
                  } 
                }
              }
            }
          },

        }
      }

Никто из них не работает. Я хочу получить только те результаты, где найдена точная строка 'test / stack'. Любая помощь будет высоко оценена.

Пример данных, которые я пытаюсь добавить:

[
{"url": "test stack",
"userId": "anotherTest",
"pageTitle": "not important",
"pageText": "not important",
"log": [1, 3, 7]
},
{"url": "test stack",
"userId": "anotherTest",
"pageTitle": "not important",
"pageText": "not important",
"log": [1, 3, 7]
},
{"url": "test stack",
"userId": "anotherTest",
"pageTitle": "not important",
"pageText": "not important",
"log": [1, 3, 7]
}
]

Спасибо.

Ответы [ 2 ]

1 голос
/ 29 января 2020

Мне удалось сделать эту работу. Шаги: 1. Удалить индекс. 2. Удалите пользовательскую функцию отображения. 3. Создайте индекс (с помощью client.indices.create). 4. Индексируйте первый элемент (с помощью client.index). 5. На этом этапе вы можете проверить в почтальоне динамические отображения c, созданные ElasticSearch (видимые только после того, как 1-й элемент проиндексирован, насколько я могу судить). Вы можете сделать запрос get по адресу http://localhost: 9200 / history / _mappings , и ответ должен выглядеть примерно так:

{
    "history": {
        "mappings": {
            "properties": {
                "fullTitle": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "log": {
                    "properties": {
                        "startTime": {
                            "type": "long"
                        },
                        "timeSpent": {
                            "type": "long"
                        }
                    }
                },
                "protocol": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "text": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "totalTimeSpent": {
                    "type": "long"
                },
                "totalVisits": {
                    "type": "long"
                },
                "url": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "userId": {
                    "type": "long"
                }
            }
        }
    }
}

Как видите, любое поле, проиндексированное как К тексту прикреплено еще одно поле, называемое ключевым словом, которое можно использовать для точных совпадений. 6. Запрос на получение точных совпадений выглядит следующим образом:

   const result = await esClient.search({
      index: 'history',
      body: {
        query: {
          term: {
            'url.keyword': {
              value: toInsert.url
            }
          }
        }
      }
    })

На данный момент вы должны получать результаты только в случае точного соответствия для поля «url» в моем случае. Надеюсь, это поможет кому-то еще. Спасибо @ibexit за попытку помочь мне.

0 голосов
/ 29 января 2020

Я вижу две проблемы:

  1. Отображение, определенное для поля URL, говорит:

    url: {тип: "ключевое слово", индекс: false, анализатор: ' ключевое слово '},

    Если вы определите index: false, поле вообще не будет доступно для поиска. Использование следующего сопоставления должно работать правильно:

    url: {тип: "ключевое слово"}

    См. https://www.elastic.co/guide/en/elasticsearch/reference/current/keyword.html для получения более подробной информации

  2. Отображенные поля ключевых слов не будут соответствовать запросу match, который предназначен для запроса текстовых полей. Пожалуйста, используйте термин запрос вместо ключевых слов. Обратите внимание на приведенный ниже пример с использованием API Elasticseaech Query:

    GET / _search {"query": {"term": {"url": {<< = поле для поиска "value": "тестовый стек "<< = искомое значение}}} <br>}

    Вот соответствующая документация: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...