0
votes

Elastic search is not recognizing my list of objects as a nested type. I would like for that to happen automatically without needing to update mapping for every such field. I need the response of _mappings api to have some sort of identifier that distinguishes properties which are of list type.

For ex: When i index such a document on a new test index ('mapping_index')

{
    "text":"value",
    "list":[{"a":"b","c":"d"},{"a":"q","c":"f"}]
}

and hit mappings api

localhost:9200/mapping_index/_mapping

I get

{
    "mapping_index": {
        "mappings": {
            "_doc": {
                "properties": {
                    "list": {
                        "properties": {
                            "a": {
                                "type": "text",
                                "fields": {
                                    "keyword": {
                                        "type": "keyword",
                                        "ignore_above": 256
                                    }
                                }
                            },
                            "c": {
                                "type": "text",
                                "fields": {
                                    "keyword": {
                                        "type": "keyword",
                                        "ignore_above": 256
                                    }
                                }
                            }
                        }
                    },
                    "text": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    }
                }
            }
        }
    }
}

I would want something like

"type" : "nested"

for the "list" key in this response so that another service which uses these fields stored in ES can be conveyed that this "list" is a multivalue key.

I've read about dynamic templates and think it might be able to help me but i'm not really sure (https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-templates.html).

Any help is much appreciated.

1
You could try this - First define a mapping in which you can specify nested type (there are APIs available to just define your desired schema ) . then check with '/_mapping' if it got applied . then you can index the data . i use this approach while indexing from python-code.Sowjanya R Bhat
@SowjanyaRBhat as I've mentioned in the question that's exactly the kind of manual effort i'm trying to avoid. I wan't ES to understand it automatically. Is that possible ?Krittam Kothari
i dont think so . you can see as per someone's answer also - manually call PUT API on 'mapping' - which is the same effort as defining 'mapping' before indexing . One question - what backend are you using to perform this indexing task ?Sowjanya R Bhat

1 Answers

0
votes

You can use dynamic_templates

match_mapping_type: "object" will take any object type change it to nested

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

Data:

{
  "list": [
    {
      "a": "b",
      "c": "d"
    },
    {
      "a": "q",
      "c": "f"
    }
  ]
}

Result:

 "index80" : {
    "mappings" : {
      "dynamic_templates" : [
        {
          "objects" : {
            "match" : "*",
            "match_mapping_type" : "object",
            "mapping" : {
              "type" : "nested"
            }
          }
        }
      ],
      "properties" : {
        "list" : {
          "type" : "nested",
          "properties" : {
            "a" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "c" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            }
          }
        }
      }
    }
  }
}