python elasticsearch bulk index数据类型

时间:2017-06-22 09:54:26

标签: python elasticsearch

我使用以下代码在弹性搜索中创建索引和加载数据

from elasticsearch import helpers, Elasticsearch
import csv
es = Elasticsearch()
es = Elasticsearch('localhost:9200')
index_name='wordcloud_data'
with open('./csv-data/' + index_name +'.csv') as f:
    reader = csv.DictReader(f)
    helpers.bulk(es, reader, index=index_name, doc_type='my-type')

print ("done")

我的CSV数据如下

date,word_data,word_count
2017-06-17,luxury vehicle,11
2017-06-17,signifies acceptance,17
2017-06-17,agency imposed,16
2017-06-17,customer appreciation,11

数据加载正常,但数据类型不准确 如何强制它说word_count是整数而不是文本 看看它如何计算出日期类型? 有没有办法可以自动找出int数据类型?或通过传递一些参数?

如果我愿意,我该怎么做才能增加ignore_above或删除某些字段。基本上没有限制字符数?

{
  "wordcloud_data" : {
    "mappings" : {
      "my-type" : {
        "properties" : {
          "date" : {
            "type" : "date"
          },
          "word_count" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          },
          "word_data" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          }
        }
      }
    }
  }
}

2 个答案:

答案 0 :(得分:2)

您需要create a mapping来描述字段类型。

使用elasticsearch-py客户端,可以使用es.indices.put_mappingindex.create方法完成此操作,方法是传递描述映射的JSON文档like shown in this SO answer。它会是这样的:

es.indices.put_mapping(
    index="wordcloud_data",
    doc_type="my-type",
    body={
        "properties": {  
            "date": {"type":"date"},
            "word_data": {"type": "text"},
            "word_count": {"type": "integer"}
        }
    }
)

但是,我建议您查看提供elasticsearch-dslmuch nicer declarative API to describe things包。这将是沿着这些方向(未经测试):

from elasticsearch_dsl import DocType, Date, Integer, Text
from elasticsearch_dsl.connections import connections
from elasticsearch.helpers import bulk

connections.create_connection(hosts=["localhost"])

class WordCloud(DocType):
    word_data = Text()
    word_count = Integer()
    date = Date()

    class Meta:
        index = "wordcloud_data"
        doc_type = "my-type"   # If you need it to be called so

WordCloud.init()
with open("./csv-data/%s.csv" % index_name) as f:
    reader = csv.DictReader(f)
    bulk(
        connections.get_connection(),
        (WordCloud(**row).to_dict(True) for row in reader)
    )

请注意,我没有尝试过我发布的代码 - 只是写了它。没有ES服务器可以进行测试。那里可能会有一些小错误或错别字(如果有的话请指出),但总体思路应该是正确的。

答案 1 :(得分:1)

谢谢。 @drdaeman的解决方案为我工作。虽然,我认为值得一提的是elasticsearch-dsl 6 +

class Meta:
     index = "wordcloud_data"
     doc_type = "my-type"

此代码段将引发cannot write to wildcard index异常。将以下内容更改为

class Index:
   name = 'wordcloud_data'
   doc_type = 'my_type'