【问题标题】:elasticsearch dynamic field nested detectionelasticsearch动态字段嵌套检测
【发布时间】:2017-12-12 07:13:53
【问题描述】:

您好,我试图在我的弹性搜索中创建一个索引而不定义映射,所以我所做的就是这样。

PUT my_index1/my_type/1
{
  "group" : "fans",
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith",
      "age" :  "1",
      "enabled": false
    },
    {
      "first" : "Alice",
      "last" :  "White",
      "age" :  "10",
      "enabled": true
    }
  ]
}

如果这个弹性搜索会为这个索引创建一个映射,结果是

{
   "my_index1": {
      "mappings": {
         "my_type": {
            "properties": {
               "group": {
                  "type": "text",
                  "fields": {
                     "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                     }
                  }
               },
               "user": {
                  "properties": {
                     "age": {
                        "type": "text",
                        "fields": {
                           "keyword": {
                              "type": "keyword",
                              "ignore_above": 256
                           }
                        }
                     },
                     "enabled": {
                        "type": "boolean"
                     },
                     "first": {
                        "type": "text",
                        "fields": {
                           "keyword": {
                              "type": "keyword",
                              "ignore_above": 256
                           }
                        }
                     },
                     "last": {
                        "type": "text",
                        "fields": {
                           "keyword": {
                              "type": "keyword",
                              "ignore_above": 256
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }
}

如果您注意到属性用户没有嵌套的类型,其他属性具有由弹性搜索定义的自己的类型,有没有办法自动映射用户属性应该是这样的

"user": {
type:"nested"
                  "properties": {
                     "age": {
                        "type": "text",
                        "fields": {
                           "keyword": {
                              "type": "keyword",
                              "ignore_above": 256
                           }
                        }
                     },
                     "enabled": {
                        "type": "boolean"
                     },
                     "first": {
                        "type": "text",
                        "fields": {
                           "keyword": {
                              "type": "keyword",
                              "ignore_above": 256
                           }
                        }
                     },
                     "last": {
                        "type": "text",
                        "fields": {
                           "keyword": {
                              "type": "keyword",
                              "ignore_above": 256
                           }
                        }
                     }
                  }
               }
            }

这是缺失的。我目前正在使用巢

有没有办法定义一个动态映射来检测索引上新添加的数据是否嵌套?

【问题讨论】:

    标签: elasticsearch nest


    【解决方案1】:

    默认情况下,Elasticsearch/Lucene 没有内部对象的概念。因此,它将对象层次结构扁平化为字段名称和值的简单列表。

    上面的文档将在内部转换成一个看起来更像这样的文档:(有关详细信息,请参阅Nested field type

    {
      "group" :        "fans",
      "user.first" : [ "alice", "john" ],
      "user.last" :  [ "smith", "white" ]
    }
    

    这里没有漂亮的答案。一种常见的做法可能是使用动态模板将object 转换为nested(但是,副作用是所有object 类型的字段都会更改为nested 类型),

    {
        "mappings": {
            "dynamic_templates": [
                {
                    "objects": {
                        "match": "*",
                        "match_mapping_type": "object",
                        "mapping": {
                            "type": "nested"
                        }
                    }
                }
            ]
        }
    }
    

    另一种方法是在插入数据之前指定字段的映射。

    PUT <your index>
    {
      "mappings": {
        "properties": {
          "user": {
            "type": "nested" 
          }
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      您可以定义一个dynamic template,您可以在其中定义您自己的自定义映射,以便稍后在索引中索引文档时使用。

      添加一步一步的过程,在此过程的帮助下自动将user字段的映射映射到nested类型的映射

      首先,您需要为索引定义一个动态模板,如下所示,其中有一个match 参数,它将匹配具有类似于user* 的模式的字段名称并将其映射到nested 类型

      PUT /<index-name>
      {
        "mappings": {
          "dynamic_templates": [
            {
              "nested_users": {
                "match": "user*",
                "mapping": {
                  "type": "nested"
                }
              }
            }
          ]
        }
      }
      

      创建此模板后,您需要将文档索引到其中

      POST /<index-name>/_doc/1
      {
        "group": "fans",
        "user": [
          {
            "first": "John",
            "last": "Smith",
            "age": "1",
            "enabled": false
          },
          {
            "first": "Alice",
            "last": "White",
            "age": "10",
            "enabled": true
          }
        ]
      }
      

      现在,当您使用Get Mapping API 看到索引文档的映射时,映射将与您期望看到的相似

      GET /<index-name>/_mapping?pretty
      {
        "index-name": {
          "mappings": {
            "dynamic_templates": [
              {
                "nested_users": {
                  "match": "user*",
                  "mapping": {
                    "type": "nested"
                  }
                }
              }
            ],
            "properties": {
              "group": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "user": {
                "type": "nested",                  // note this
                "properties": {
                  "age": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "first": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "last": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
      

      或者正如@Jacky1205 提到的,如果它不是特定于字段的,那么您可以使用下面的模板,它将所有object 类型字段匹配为nested 类型

      {
        "mappings": {
          "dynamic_templates": [
            {
              "nested_users": {
                "match": "*",
                "match_mapping_type": "object",
                "mapping": {
                  "type": "nested"
                }
              }
            }
          ]
        }
      }
      

      【讨论】:

      • @Pants 请仔细阅读答案,如果这解决了您的问题,请告诉我?
      猜你喜欢
      • 1970-01-01
      • 2015-07-30
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      相关资源
      最近更新 更多