【问题标题】:Passing variables onto a MongoDB Query将变量传递到 MongoDB 查询
【发布时间】:2015-11-16 06:38:37
【问题描述】:

我的收藏有以下文件

{
  cust_id: "0044234",
  Address: "1234 Dunn Hill",
  city: "Pittsburg",
  comments : "4"
},

{
  cust_id: "0097314",
  Address: "5678 Dunn Hill",
  city: "San Diego",
  comments : "99"
},

{
  cust_id: "012345",
  Address: "2929 Dunn Hill",
  city: "Pittsburg",
  comments : "41"
}

我想编写一段代码来提取和存储来自同一个城市的所有 cust_id。我可以通过在 MongoDB 上运行以下查询来得到答案:

db.custData.find({"city" : 'Pittsburg'},{business_id:1}). 

但是,我无法使用 Python 做同样的事情。以下是我尝试过的:

ctgrp=[{"$group":{"_id":"$city","number of cust":{"$sum":1}}}]
myDict={}
for line in collection.aggregate(ctgrp) : #for grouping all the cities in   the dataset
    myDict[line['_id']]=line['number of cust']
for key in myDict:
    k=db.collection.find({"city" : 'key'},{'cust_id:1'})
    print k
client.close()

另外,我无法弄清楚如何存储它。我唯一想到的是一本字典,其中有一个与特定“键”相对应的“值列表”。但是,我想不出一个大致相同的实现。我正在寻找这样的输出

对于匹兹堡,值为 0044234 和 012345。

【问题讨论】:

  • 您的预期结果是什么?使用您问题上的edit 链接添加它。还有 pymongo Tutorial
  • 我已经给出了预期的输出。对于键“Pittsburg”,值应为“0044234”和“012345”。或者,如果有更好的存储方式来代替这个。
  • 所以如果我是正确的,你想得到一个像['0044234', '012345'] 这样的列表。 cust_id 也很明显吧?
  • 是的。确切地。我想要这个与字典中键“匹兹堡”相对应的“值”列表。 Cust_id 是不同的,只有在对其进行分组之后(正如我在代码中所做的那样)。否则,该集合最初包含许多具有相同 cust_id 的文档。

标签: python mongodb mongodb-query pymongo aggregation-framework


【解决方案1】:

您可以使用.distinct 方法,这是最好的方法。

import pymongo
client = pymongo.MongoClient()
db = client.test
collection = db.collection

然后:

collection.distinct('cust_id', {'city': 'Pittsburg'})

产量:

['0044234', '012345']

或者做这个效率不高的客户端:

>>> cust_ids = set()
>>> for element in collection.find({'city': 'Pittsburg'}):
...     cust_ids.add(element['cust_id'])
... 
>>> cust_ids
{'0044234', '012345'}

现在,如果您想要给定城市的所有“cust_id”,那就是

 >>> list(collection.aggregate([{'$match': {'city': 'Pittsburg'} }, {'$group': {'_id': None, 'cust_ids': {'$push': '$cust_id'}}}]))[0]['cust_ids']
['0044234', '012345']

现在,如果您想要按城市对文档进行分组,然后在这里找到不同的“cust_id”,那么就是这里:

>>> from pprint import pprint
>>> pipeline = [{'$group': {'_id': '$city', 'cust_ids': {'$addToSet': '$cust_id'}, 'count': {'$sum': 1}}}]
>>> pprint(list(collection.aggregate(pipeline)))
[{'_id': 'San Diego', 'count': 1, 'cust_ids': ['0097314']},
 {'_id': 'Pittsburg', 'count': 2, 'cust_ids': ['012345', '0044234']}]

【讨论】:

  • 但我希望动态传递值,而不是明确指定“匹兹堡”。我刚刚在匹兹堡的帮助下举例说明了一个例子。如果您仔细查看代码的第 5 行和第 6 行,我想您会明白我在做什么。在这里,每次循环迭代时,'key' 将是不同的城市名称。另外,您能否解释一下您所说的“客户端”是什么意思?
  • 非常感谢。这行得通。不过,我仍然有一个疑问——变量“管道”的数据结构是什么?我想知道这一点,因为我需要在此之上执行类似的操作。因此,我必须存储这些值才能使用它们,而不仅仅是打印它们。我的意思是这样的:对于与特定城市相对应的每个 cust_id,我必须从另一个集合中找到它们的 bag_id。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-15
相关资源
最近更新 更多