【问题标题】:How to store data in elasticsearch _source but not index it?如何将数据存储在 elasticsearch _source 中但不对其进行索引?
【发布时间】:2015-06-16 03:51:21
【问题描述】:

我只搜索几个字段,但我希望能够将整个文档存储在 ES 中,以免额外的 DB (MySQL) 查询。

我尝试将index: nostore: 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 属性呢?

【问题讨论】:

    标签: elasticsearch mapping


    【解决方案1】:

    默认情况下,无论您选择索引的字段如何,都会存储文档的_source_source 用于在搜索结果中返回文档,而被索引的字段用于搜索。

    您不能在对象上设置 index: no 以防止对象中的所有字段都被索引,但您可以使用 Dynamic Templates 执行您想要的操作,使用 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"
            }
        ]
    }
    

    如果您使用搜索词 booktitle 字段上进行搜索,则会返回该文档。如果您在 author.first_nameauthor.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 索引并查看哪些字段已被索引。

    【讨论】:

    • "index": "no" 是否暗示 "store": "no" ?我读过store 意味着将原始属性的_source 存储在lucene 中,但我不确定它与index 有什么关系。只是为了确保 - 我不必为非索引字段提供映射?如果我放置一个属性 X 为 int 的文档,然后放置一个具有相同属性但带有字符串的文档,ES 不会抛出错误?
    • 否,index 的设置并不能决定 store 的设置。 store 的默认值为 no,这在您的用例中很好,因为 _source 已启用。如果禁用 _source 字段并选择要存储的字段,则存储的字段仅在匹配时才会在搜索结果中返回。您必须为非索引字段提供映射,以便告​​诉 Elasticsearch 不要索引它们,否则 Elasticsearch 将使用默认分析器(标准分析器)来索引该字段。
    • 但是,在上面的示例中,动态模板用于非索引字段的映射。如果您没有字段映射,则更改属性类型时不会返回错误。
    【解决方案2】:

    您可以在映射定义中简单地设置 "enabled": false

    enabled 设置只能应用于顶级映射定义和对象字段,导致 Elasticsearch 完全跳过对字段内容的解析。 JSON 仍然可以从 _source 字段中检索到,但不可搜索或以任何其他方式存储。

    "mappings": {
      "properties": {
        "title": { "type": "text" },
        "author": { "type": "object", "enabled": false }
      }
    }
    

    但请注意 enabled 不适用于核心类型,但 index 选项可以通过设置 "index": false 来应用于核心类型。

    index 选项控制是否对字段值进行索引。它接受真或假,默认为真。未编入索引的字段不可查询。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-20
      • 1970-01-01
      • 1970-01-01
      • 2012-04-15
      • 2019-01-26
      • 1970-01-01
      相关资源
      最近更新 更多