Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Elasticsearch无法解析作为对象来自pymongo的datetime字段_Python_Mongodb_<img Src="//i.stack.imgur.com/RUiNP.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">elasticsearch_Pymongo - Fatal编程技术网 elasticsearch,pymongo,Python,Mongodb,elasticsearch,Pymongo" /> elasticsearch,pymongo,Python,Mongodb,elasticsearch,Pymongo" />

Python Elasticsearch无法解析作为对象来自pymongo的datetime字段

Python Elasticsearch无法解析作为对象来自pymongo的datetime字段,python,mongodb,elasticsearch,pymongo,Python,Mongodb,elasticsearch,Pymongo,我正在尝试使用pymongo和Python客户端Elasticsearch将数据从mongoDB流式传输到Elasticsearch 我已经设置了一个映射,我在这里报告与感兴趣的字段相关的代码片段: “更新地址”:{ “类型”:“日期”, “格式”:“dateOptionalTime” } 我的脚本使用pymongo从MongoDB中获取每个文档,并尝试将其索引到Elasticsearch中 from elasticsearch import Elasticsearch from pymongo

我正在尝试使用pymongo和Python客户端Elasticsearch将数据从mongoDB流式传输到Elasticsearch

我已经设置了一个映射,我在这里报告与感兴趣的字段相关的代码片段:

“更新地址”:{ “类型”:“日期”, “格式”:“dateOptionalTime” }

我的脚本使用pymongo从MongoDB中获取每个文档,并尝试将其索引到Elasticsearch中

from elasticsearch import Elasticsearch
from pymongo import MongoClient

mongo_client = MongoClient('localhost', 27017)
es_client = Elasticsearch(hosts=[{"host": "localhost", "port": 9200}])
db = mongo_client['my_db']
collection = db['my_collection']

for doc in collection.find():
    es_client.index(
         index='index_name', 
         doc_type='my_type', 
         id=str(doc['_id']), 
         body=json.dumps(doc, default=json_util.default)
    )
我在运行时遇到的问题是:

elasticsearch.exceptions.RequestError:TransportError(400,u'MapperParsingException[未能解析[Update_at]];嵌套:ElasticsearchIllegalArgumentException[未知属性[$date]];')

我认为问题的根源在于pymongo将更新的字段作为datetime.datetime对象序列化,如果我在for循环中打印文档,我可以看到:

更新时间:datetime.datetime(2014,8,31,17,18,13,17000)

这与Elasticsearch查找映射中指定的日期类型的对象相冲突


有什么办法可以解决这个问题吗?

您走的是正确的道路,您的Python
datetime
需要序列化为日期字符串。因此,您需要在
json.dumps()调用中添加
CustomEncoder
。首先,将您的
CustomEncoder
声明为
jsonecoder
的子类,该子类将处理
datetime
time
属性的转换,但将其余部分委托给其超类:

class CustomEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime('%Y-%m-%dT%H:%M:%S%z')
        if isinstance(obj, time):
            return obj.strftime('%H:%M:%S')
        if hasattr(obj, 'to_json'):
            return obj.to_json()
        return super(CustomEncoder, self).default(obj)
然后您可以在
json.dumps
调用中使用它,如下所示:

...
body=json.dumps(doc, default=json_util.default, cls=CustomEncoder)
...

我猜你的问题是你在使用

body=json.dumps(doc, default=json_util.default)
但你应该使用

body=doc
这样做对我来说是可行的,因为elasticsearch似乎关心将字典的别名转换成JSON文档(当然,假设doc是一个字典,我猜是这样)

至少在我使用的elasticsearch版本(2.x)中,datetime.datetime的别名是正确的,不需要映射。例如,这对我很有用:

doc = {"updated_on": datetime.now(timezone.utc)}
res = es.index(index=es_index, doc_type='my_type',
               id=1, body=doc)

Kibana将其识别为日期。

这解决了datetime对象的序列化问题:正文中的字段现在是“updated_at”:{“$date”:1409505493017}。然而,我得到了同样的错误,所以这个问题肯定是其他一些问题。