解析密钥:列表中的值对

时间:2014-09-03 16:19:48

标签: python pymongo

我在数组中继承了具有键:值对的Mongo结构。我需要在下面的标签中提取收集和消耗的值,但是我没有看到使用Mongo查询文档中的$ regex命令执行此操作的简单方法。

    {
    "_id" : "94204a81-9540-4ba8-bb93-fc5475c278dc"
    "tags" : ["collected:172", "donuts_used:1", "spent:150"]
    }

提取这些值的理想输出是在使用pymongo查询它们时将它们转储为下面的格式。我真的不知道如何最好地只返回我需要的值。请指教。

94204a81-9540-4ba8-bb93-fc5475c278dc,172,150

3 个答案:

答案 0 :(得分:1)

如果您在编写mongo查询时遇到困难(列表中的元素实际上是字符串而不是需要解析的键值),这里的普通Python解决方案可能会有所帮助。

>>> import pymongo
>>> from pymongo import MongoClient
>>> client = MongoClient('localhost', 27017)
>>> db = client['test']
>>> collection = db['stackoverflow']
>>> collection.find_one()
{u'_id': u'94204a81-9540-4ba8-bb93-fc5475c278dc', u'tags': [u'collected:172', u'donuts_used:1', u'spent:150']}
>>> record = collection.find_one()
>>> print record['_id'], record['tags'][0].split(':')[-1], record['tags'][2].split(':')[-1]
94204a81-9540-4ba8-bb93-fc5475c278dc 172 150

您可以在此处使用适当的函数检索所有记录,而不是使用find_one(),并且可以浏览每条记录。我不确定你的数据是多么一致,所以我使用列表中的第一个和第三个元素进行硬编码...你可以想要调整那个部分并尝试除了记录级别。

答案 1 :(得分:1)

print d['_id'], ' '.join([ x.replace('collected:', '').replace('spent:', '')\
    for x in d['tags'] if 'collected' in x or 'spent' in x ] )
>>>
94204a81-9540-4ba8-bb93-fc5475c278dc 172 150

答案 2 :(得分:0)

这是一种方法,如果您拥有的是JSON对象示例。

请注意有关标签订购等的说明。最好修改“架构”,以便在调用时更方便地查询,收集和汇总“标签”。

import re

# Returns csv string of _id, collected, used
def parse(obj):
    _id         = obj["_id"]
    # This is terribly brittle since the insertion of any other type of tag
    # between 'c' and 's' will cause these indices to be messed up. 
    # It is probably much better to directly query these, or store them as individual
    # entities in your mongo "schema".
    collected   = re.sub(r"collected:(\d+)", r"\1", obj["tags"][0])
    spent       = re.sub(r"spent:(\d+)", r"\1", obj["tags"][2])
    return ", ".join([_id, collected, spent])

# Some sample object
parse_me = {
    "_id" : "94204a81-9540-4ba8-bb93-fc5475c278dc"
    "tags" : ["collected:172", "donuts_used:1", "spent:150"]
}
print parse(parse_me)