我正试图在我的架构中删除iPad的最低价格。我知道如何使用pymongo找到它,但我不知道如何删除它。 这是我的架构:
{
"_id": "sjobs",
"items": [
{
"type": "iPod",
"price": 20.00
},
{
"type": "iPad",
"price": 399.99
},
{
"type": "iPad",
"price": 199.99
},
{
"type": "iPhone 5",
"price": 300.45
}
]
}
{
"_id": "bgates",
"items": [
{
"type": "MacBook",
"price": 2900.99
},
{
"type": "iPad",
"price": 399.99
},
{
"type": "iPhone 4",
"price": 100.00
},
{
"type": "iPad",
"price": 99.99
}
]
}
我有一个python循环,找到iPad的最低销售价格:
cursor = db.sales.find({'items.type': 'iPad'}).sort([('items', pymongo.DESCENDING)])
for doc in cursor:
cntr = 0
for item in doc['items']:
if item['type'] == 'iPad' and resetCntr == 0:
cntr = 1
sales.update(doc, {'$pull': {'items': {item['type']}}})
这不起作用。我需要做些什么来删除最低的iPad价格项目?
答案 0 :(得分:2)
您的Python代码没有按照您的想法执行(除非您没有包含很多内容)。您不需要在客户端进行排序和迭代 - 您应该让服务器完成工作。运行这个聚合管道(我给出了shell语法,你当然可以从Python调用它):
> r = db.sales.aggregate( {"$match" : { "items.type":"iPad"} },
{"$unwind" : "$items"},
{"$match" : { "items.type":"iPad"} },
{"$group" : { "_id" : "$_id",
"lowest" : {"$min":"$items.price"},
"count":{$sum:1}
}
},
{"$match" : {count:{$gt:1}}}
);
{
"result" : [
{
"_id" : "bgates",
"lowest" : 99.99,
"count" : 2
},
{
"_id" : "sjobs",
"lowest" : 199.99,
"count" : 2
}
],
"ok" : 1
}
现在您可以遍历“r.results”数组并执行更新:
db.sales.update( { "_id" : r.results[0]._id },
{ "$pull" : { "items" : { "type" : "iPad", "price" : r.result[0].lowest}}} );
请注意,我只包含有多个iPad的记录 - 否则您最终可能会删除阵列中唯一的iPad记录。如果您要删除所有“非最高”价格,那么您需要查找价格最高且$pull
所有元素$lt
。
答案 1 :(得分:1)
免责声明:以下代码未经过测试,因为我没有在本地安装mongo。然而,我确实花了我的时间写它,所以我非常有信心它接近工作
def remove_lowest_price(collection):
cursor = collection.find({}, {'items': 1})
for doc in cursor:
items = doc['items']
id = doc['_id']
for item in items:
lowest_price = 100000 # a huge number
if item['type'] == 'i_pad' and item['price'] < lowest:
lowest = item['price']
# lowest now contains the price of the cheapest ipad
collection.update(
{'_id': id},
{'$pull': {'items': {'price': lowest}}}
)
当然,如果另一件物品的价格完全相同,那么这里会有问题,但我认为从这里开始很容易改进
答案 2 :(得分:0)
{'$pull': {'items': {item['type']}}}
这看起来不像有效的json,是吗?
在你的例子中,不应该是“sales.update(...)”是“db.sales.update(...)”吗?
也许最好在更新操作中进行查询:
db.sales.update({_id: doc[_id]}, ...)
而不是整个文档。
最后更新正文可能是
{'$pull': {'items': {type: item['type']}}}