Как хранить данные в elasticsearch _source, но не индексировать его? - программирование

Как хранить данные в elasticsearch _source, но не индексировать его?

Я ищу только пару полей, но хочу иметь возможность хранить весь документ в ES, чтобы не добавлять дополнительные запросы к БД (MySQL).

Я попытался добавить index: no, store: no к целым объектам/свойствам в сопоставлении, но я все еще не уверен, что индексы индексируются и добавляют лишние служебные данные.

Скажем, у меня есть книги и у каждого есть автор. Я хочу искать только по названию книги, но хочу получить весь документ.

Это нормально:

mappings:
properties:
    title:
        type: string
        index: analyzed
    author:
        type: object
        index: no
        store: no
        properties:
            first_name:
                type: string
            last_name:
                type: string

Или мне лучше делать:

mappings:
properties:
    title:
        type: string
        index: analyzed
    author:
        type: object
        properties:
            first_name:
                index: no
                store: no
                type: string
            last_name:
                index: no
                store: no
                type: string

Или, может быть, я делаю это совершенно неправильно? А как насчет свойств nested, которые не следует индексировать?

4b9b3361

Ответ 1

По умолчанию _source документа сохраняется независимо от полей, которые вы хотите индексировать. _source используется для возврата документа в результаты поиска, тогда как поля, которые индексируются, используются для поиска.

Вы не можете установить index: no на объект, чтобы все индексы индексировались, но вы можете делать то, что хотите, с Динамические шаблоны, используя path_match, чтобы применить параметр index: no к каждому полю внутри объекта. Вот простой пример.

Создайте индекс с вашим сопоставлением, включающим динамические шаблоны для объекта author и вложенного объекта categories:

POST /shop
{
    "mappings": {
        "book": {
            "dynamic_templates": [
                {
                    "author_object_template": {
                        "path_match": "author.*",
                        "mapping": {
                            "index": "no"
                        }
                    }
                },
                {
                    "categories_object_template": {
                        "path_match": "categories.*",
                        "mapping": {
                            "index": "no"
                        }
                    }
                }
            ],
            "properties": {
                "categories": {
                    "type": "nested"
                }
            }
        }
    }
}

Укажите документ:

POST /shop/book/1
{
    "title": "book one",
    "author": {
        "first_name": "jon",
        "last_name": "doe"
    },
    "categories": [
        {
            "cat_id": 1,
            "cat_name": "category one"
        },
        {
            "cat_id": 2,
            "cat_name": "category two"
        }
    ]
}

Если вы искали в поле title с поисковым термином book, документ будет возвращен. Если вы выполните поиск по author.first_name или author.last_name, совпадение не будет, потому что эти поля не были проиндексированы:

POST /shop/book/_search
{
    "query": {
        "match": {
            "author.first_name": "jon"
        }
    }
}

То же самое было бы для вложенного запроса в полях категорий:

POST /shop/book/_search
{
    "query": {
        "nested": {
            "path": "categories",
            "query": {
                "match": {
                    "categories.cat_name": "category"
                }
            }
        }
    }
}

Также вы можете использовать инструмент Luke, чтобы ожидать индекса Lucene и посмотреть, какие поля были проиндексированы.