【问题标题】:Elasticsearch - what is the difference between properties and fields?Elasticsearch - 属性和字段有什么区别?
【发布时间】:2018-08-20 07:03:34
【问题描述】:

我一直在阅读这两个关于属性和字段的文档:

https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/properties.html

我了解具体文档中描述的每个属性的目的(这意味着我了解属性的用途并且我了解多字段的目的),但我并没有真正看到它们实际所做的事情之间的区别..例如,在从字段文档中获取的代码 sn-p 中显示了如何定义多字段:

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "city": {
          "type": "text",
          "fields": {
            "raw": { 
              "type":  "keyword"
            }
          }
        }
      }
    }
  }
}

如果我将“字段”这个词换成“属性”,它会不会完全一样?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    如果您只是在示例中将fields 替换为properties,那么作为Biplab said,Elasticsearch 会给您一个例外:

        "reason": "Failed to parse mapping [doc]: Mapping definition for [city] \
          has unsupported parameters:  [properties : {raw={type=keyword}}]",
    

    那么properties 是什么?

    properties 基本上声明你将在这里发送一个复杂的 JSON 对象。

    在您的示例中使用 properties 而不是 fields 的最接近映射如下所示:

    PUT my_index_with_properties
    {
      "mappings": {
        "doc": {
          "properties": {
            "city": {
              "properties": {
                "name": {
                  "type": "text"
                },
                "name_keyword": {
                  "type": "keyword"
                }
              }
            }
          }
        }
      }
    }
    

    您必须插入的文档将如下所示:

    POST my_index_with_properties/doc
    {
      "city": {
        "name": "New York",
        "name_keyword": "New York"
      }
    }
    

    注意"New York" 重复了两次。

    在这里您可以使用match 发出全文查询:

    POST my_index_with_properties/doc/_search
    {
      "query": {
        "match": {
          "city.name": "york"
        }
      }
    }
    

    或使用term query 进行精确搜索:

    POST my_index_with_properties/doc/_search
    {
      "query": {
        "term": {
          "city.name_keyword": "New York"
        }
      }
    }
    

    请注意,我们正在查询不同的字段。

    它和fields有什么不同?

    使用fields 的示例,正​​如您发布的那样,我们可以发送如下所示的文档:

    POST my_index/doc
    {
      "city": "New York"
    }
    

    如您所见,没有明确的数据重复。但实际上,在 Elasticsearch 的底层为你做了这种复制。

    现在我们可以使用city 字段进行全文搜索:

    POST my_index/doc/_search
    {
      "query": {
        "match": {
          "city": "york"
        }
      }
    }
    

    但它不适用于精确搜索。以下查询将不返回任何内容,因为字段 city 已标记化并小写,而 term 查询的参数不是:

    POST my_index/doc/_search
    {
      "query": {
        "term": {
          "city": "New York"
        }
      }
    }
    

    这个确切的搜索查询将起作用:

    POST my_index/doc/_search
    {
      "query": {
        "term": {
          "city.keyword": "New York"
        }
      }
    }
    

    由于映射中的fields,我们刚刚要求Elasticsearch 再次索引该city 字段,作为keyword,并且要使用该字段,我们必须输入city.keyword

    因此,作为结论,fields 只是告诉 Elasticsearch 您希望它以多种不同方式处理相同数据字段的一种方式。例如,在索引不同语言的文本时,它可能会派上用场。

    【讨论】:

    • 那么当您将值发布到具有字段的属性时,该值会自动写入该字段吗?如果我们对同一个属性有多个字段并且都具有不同的类型怎么办..如何处理值?
    • @YonatanNir “如果我们有多个字段指向同一个属性”是什么意思?如果有一个 JSON 包含多个具有不同值类型的字段?那么你就不能使用fields - 它只适用于一个给定的 JSON 字段。
    • 我不能例如创建一个文本类型的属性,它有 2 个字段,一个是关键字,一个是完全像数字或其他东西的东西?
    • @YonatanNir 我认为它应该可以工作(只要该值可以解析为数字)。当没有定义映射并且 ES 必须从 JSON 中推断它时,它会为每个“字符串”字段创建一个带有 keyword 字段的 text 属性(因此可以发出全文和精确搜索)。跨度>
    【解决方案2】:

    根据“字段”的 Elasticsearch 文档:

    以不同的方式索引相同的字段通常很有用 不同的目的。这就是多领域的目的。例如, 字符串字段可以映射为全文搜索的文本字段, 并作为排序或聚合的关键字字段:

    考虑到上面的语句和你的JSON,如果你想用“city”作为文本和“keyword”,你需要在“fields”下声明另一个类型,这样你就可以像查询

    "sort": {
      "city.raw": "asc" 
    }
    

    【讨论】:

    • 我明白这一点。但我不明白如果不是“字段”这个词我会写在那里“属性”会有什么区别。属性文档也描述了一个点符号
    • elasticsearch 会抛出异常。归档(在本例中为城市)不能有属性“properties”
    猜你喜欢
    • 2019-03-07
    • 2021-09-03
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 2016-01-27
    • 2011-11-14
    相关资源
    最近更新 更多