48

I can set mappings of index being created in curl command like this:

{  
  "mappings":{  
    "logs_june":{  
      "_timestamp":{  
        "enabled":"true"
      },
      "properties":{  
        "logdate":{  
          "type":"date",
          "format":"dd/MM/yyy HH:mm:ss"
        }
      }
    }
  }
}

But I need to create that index with elasticsearch client in python and set mappings.. what is the way ? I tried somethings below but not work:

self.elastic_con = Elasticsearch([host], verify_certs=True)
self.elastic_con.indices.create(index="accesslog", ignore=400)
params = "{\"mappings\":{\"logs_june\":{\"_timestamp\": {\"enabled\": \"true\"},\"properties\":{\"logdate\":{\"type\":\"date\",\"format\":\"dd/MM/yyy HH:mm:ss\"}}}}}"
self.elastic_con.indices.put_mapping(index="accesslog",body=params)

4 Answers4

69

You can simply add the mapping in the create call like this:

from elasticsearch import Elasticsearch

self.elastic_con = Elasticsearch([host], verify_certs=True)
mapping = '''
{  
  "mappings":{  
    "logs_june":{  
      "_timestamp":{  
        "enabled":"true"
      },
      "properties":{  
        "logdate":{  
          "type":"date",
          "format":"dd/MM/yyy HH:mm:ss"
        }
      }
    }
  }
}'''
self.elastic_con.indices.create(index='test-index', ignore=400, body=mapping)
Renaud
  • 16,073
  • 6
  • 81
  • 79
Val
  • 207,596
  • 13
  • 358
  • 360
  • 3
    what if i want to update the mapping after creating index? – Gaurav Koradiya May 28 '20 at 10:05
  • Uascase is such that i am indexing some documents first and after indexing i need to add more property(field) in mapping in existing mapping. I have resolved it by doing "dynamic template" in ES. Thanks @Val. – Gaurav Koradiya May 29 '20 at 07:43
  • @GauravKoradiya please ask a new question specific to your use case – Val May 29 '20 at 07:50
  • Pretty sure you have to reindex if you're changing the mapping on an existing index. Also it looks like this syntax has changed. If I figure out the new way, I'll post it here. – szeitlin Feb 10 '22 at 18:59
35

Well, there is easier way to do this with general python syntax:

from elasticsearch import Elasticsearch
# conntect es
es = Elasticsearch([{'host': config.elastic_host, 'port': config.elastic_port}])
# delete index if exists
if es.indices.exists(config.elastic_urls_index):
    es.indices.delete(index=config.elastic_urls_index)
# index settings
settings = {
    "settings": {
        "number_of_shards": 1,
        "number_of_replicas": 0
    },
    "mappings": {
        "urls": {
            "properties": {
                "url": {
                    "type": "string"
                }
            }
        }
     }
}
# create index
es.indices.create(index=config.elastic_urls_index, ignore=400, body=settings)
Elzor
  • 804
  • 8
  • 8
24

The Python API client can be a tricky to work with and it often requires you to provide the inner portions of JSON spec documentations to keyword arguments.

For the put_mapping method, instead of providing it the full "mappings" JSON document you must give it the document_type parameter and only the inner portion of the "mappings" document like so:

self.client.indices.put_mapping(
    index="accesslog",
    doc_type="logs_june",
    body={
        "_timestamp": {  
            "enabled":"true"
        },
        "properties": {  
            "logdate": {  
                "type":"date",
                "format":"dd/MM/yyy HH:mm:ss"
            }
        }
    }
)
James Murty
  • 1,818
  • 1
  • 16
  • 16
  • 5
    Thank you for an example of put_mapping() instead of create()! – Ymartin Mar 07 '18 at 18:10
  • @James Murty. Thanks for the example. I was able to run the code above and didn't get any error for specifying the date type for the field. However, when I do ```GET my_index_name/_mapping/```, the ```logdate``` date field is ```string``` and is NOT ```date``` on Kibana – sharp May 17 '18 at 20:05
  • 1
    Note that `doc_type` is deprecated in ElasticSearch 7 and will be removed in version 8. If you use one index per document type, you can just leave it off. – Noumenon Mar 22 '21 at 02:47
0

Another python client sample of how to raise field limit through create index

from elasticsearch import Elasticsearch

es = Elasticsearch([{'host': config.elastic_host, 'port': 
config.elastic_port}])
settings = {
    'settings': {
        'index.mapping.total_fields.limit': 100000
    }
}

es.indices.create(index='myindex', body=settings)
Pari Rajaram
  • 422
  • 3
  • 7