Получить только совпадающие значения и соответствующие поля из ElasticSearch - PullRequest
0 голосов
/ 05 июля 2018

Допустим, у меня есть документы типа

{
  "name": "John",
  "department": "Biology",
  "address": "445 Mount Eden Road"
},
{
  "name": "Jane",
  "department": "Chemistry",
  "address": "32 Wilson Street"
},
{
  "name": "Laura",
  "department": "BioTechnology",
  "address": "21 Greens Road"
},
{
  "name": "Mark",
  "department": "Physics",
  "address": "Random UNESCO Bio-reserve"
}

Существует вариант использования, когда, если я наберу «bio» в строке поиска, я должен получить совпадающие значения поля из эластичного поиска вместе с именем поля.

Для этого примера

Ввод : "био"

Ожидаемый результат :

{
  "field": "department",
  "value": "Biology"
},
{
  "field": "department",
  "value": "BioTechnology"
},
{
  "field": "address",
  "value": "Random UNESCO Bio-reserve"
}

Какой тип запроса мне следует использовать? Я могу подумать об использовании NGram Tokenizer, а затем использовать запрос на совпадение. Но я не уверен, как мне получить в качестве выходных данных только соответствующее значение поля (не весь документ) и соответствующее имя поля.

1 Ответ

0 голосов
/ 05 июля 2018

После прочтения о подсказках завершения и подсказках контекста я мог бы решить эту проблему следующим образом:

1) Сохраните отдельное поле «предложить» для каждой записи с типом «завершение» с контекстным отображением типа «категория». Созданное мной отображение выглядит следующим образом:

{
  "properties": {
    "suggest": {
      "type": "completion",
      "contexts": [
        {
          "name": "field_type",
          "type": "category",
          "path": "cat"
        }
      ]
    },
    "name": {
      "type": "text"
    },
    "department": {
      "type": "text"
    },
    "address": {
      "type": "text"
    }
  }
}

2) Затем я вставляю записи, как показано ниже (добавляя метаданные поиска в поле «предложить» с соответствующим «контекстом»).

Например, чтобы вставить первую запись, я выполняю следующее:

POST: localhost: 9200 / test_index / test_type / 1

{
    "suggest": [
        {
            "input": ["john"],
            "contexts": {
                "field_type": ["name"] 
            }
        },
        {
            "input": ["biology"],
            "contexts": {
                "field_type": ["department"] 
            }
        },
        {
            "input": ["445 mount eden road"],
            "contexts": {
                "field_type": ["address"] 
            }
        }
    ],
    "name": "john",
    "department": "biology",
    "address": "445 mount eden road"
}

3) Если мы хотим искать термины, встречающиеся в середине предложения (поскольку поисковый термин «био» встречается в середине поля адреса в 4-й записи, мы можем проиндексировать запись следующим образом:

POST: localhost: 9200 / test_index / test_type / 4

{
    "suggest": [
        {
            "input": ["mark"],
            "contexts": {
                "field_type": ["name"] 
            }
        },
        {
            "input": ["physics"],
            "contexts": {
                "field_type": ["department"] 
            }
        },
        {
            "input": ["random unesco bio-reserve", "bio-reserve"],
            "contexts": {
                "field_type": ["address"] 
            }
        }
    ],
    "name": "mark",
    "department": "physics",
    "address": "random unesco bio-reserve"
}

4) Затем выполните поиск по ключевому слову «био» следующим образом:

локальный: 9200 / test_index / test_type / _search

{
    "_source": false,
    "suggest": {
        "suggestion" : {
            "text" : "bio",
            "completion" : {
                "field" : "suggest",
                "size": 10,
                "contexts": {
                    "field_type": [ "name", "department", "address" ]
                }
            }
        }
    }
}

Ответ:

{
    "hits": {
        "total": 0,
        "max_score": 0,
        "hits": []
    },
    "suggest": {
        "suggestion": [
            {
                "text": "bio",
                "offset": 0,
                "length": 3,
                "options": [
                    {
                        "text": "bio-reserve",
                        "_index": "test_index",
                        "_type": "test_type",
                        "_id": "4",
                        "_score": 1,
                        "contexts": {
                            "field_type": [
                                "address"
                            ]
                        }
                    },
                    {
                        "text": "biology",
                        "_index": "test_index",
                        "_type": "test_type",
                        "_id": "1",
                        "_score": 1,
                        "contexts": {
                            "field_type": [
                                "department"
                            ]
                        }
                    },
                    {
                        "text": "biotechnology",
                        "_index": "test_index",
                        "_type": "test_type",
                        "_id": "3",
                        "_score": 1,
                        "contexts": {
                            "field_type": [
                                "department"
                            ]
                        }
                    }
                ]
            }
        ]
    }
}

Может кто-нибудь предложить какой-нибудь лучший подход?

...