Search code examples
elasticsearchnest

elasticsearch dynamic field nested detection


Hi im trying to create an index in my elastic search without defining the mapping so what i did was this.

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
    }
  ]
}

if did this elastic search will create a mapping for this index which is the result is

{
   "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
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }
}

if you would notice the property user didn't have a type of nested other properties has their own type defined by elastic search is there a way to it automatically the mapping should be look like this for the user property

"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
                           }
                        }
                     }
                  }
               }
            }

which is missing. im currently using nest

is there a way to define a dynamic mapping to detect if the newly added data on index is nested?


Solution

  • By default, Elasticsearch/Lucene has no concept of inner objects. Therefore, it flattens object hierarchies into a simple list of field names and values.

    The above document would be converted internally into a document that looks more like this: (See Nested field type for more details)

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

    There is no beautiful answer here. A common approach might be using dynamic template to convert object to nested (however, a side effect is that all fields of object type would be changed to nested type),

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

    Another approach is specify mapping for the field before inserting data.

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