我是mongo的新手,我正在寻找一种简单的方法来使用一个命令进行排序和删除:
{u'house_id': 199, u'_id': ObjectId('50906d7fa3c412bb040eb896'), u'type': u'house', u'rate': 58.09608083191365}
{u'house_id': 199, u'_id': ObjectId('50906d7fa3c412bb040eb895'), u'type': u'house', u'rate': 49.34223066136407}
{u'house_id': 198, u'_id': ObjectId('50906d7fa3c412bb040eb891'), u'type': u'house', u'rate': 76.18366499496366}
{u'house_id': 198, u'_id': ObjectId('50906d7fa3c412bb040eb892'), u'type': u'house', u'rate': 17.46279901047208}
如何使用相同的house_id删除率最低的文档?
答案 0 :(得分:1)
不幸的是,remove和update命令还不允许在其中使用通用游标方法(https://jira.mongodb.org/browse/SERVER-1599),因此目前最好的方法是执行查找然后删除:
var houses = db.collection.find({house_id: 199}).sort({rate: 1});
houses.forEach(function(doc){
db.collection.remove({_id: house._id});
return;
})
这是目前最好的方式。
答案 1 :(得分:1)
虽然这里的基本答案是你需要循环结果,你可能会通过获得所有"最小值"来做得更好。一击中的文件。 aggregation framework对此非常有用,因为您可以将$first
运算符与$sort
结合使用:
var result = db.collection.aggregate([
{ "$sort": {
"house_id": 1,
"rate": 1
}},
{ "$group": {
"_id": "$house_id",
"docId": { "$first": "$_id" },
"count": { "$sum": 1 }
}},
{ "$match": {
"count": { "$gt": 1 }
}}
])
这会产生包含整个集合中所有费率最低的文档的结果,当然会丢弃任何仅为您的" house_id"因为你不想删除它。
然后,如果你真的可以逃脱它,你可以将所有这些结果应用到$in
运算符,并使用一点映射来提取您需要的_id
值:
var ids = [];
result.result.forEach(function(doc) {
ids.push( doc.docId );
});
db.collection.remove({ "_id": { "$in": ids } })
同时注意到.remove()
的默认形式将对所有匹配的文档起作用,除非指定了一个可选的运算符以仅删除一个。但这可以用于此目的。
从MongoDB 2.6,您可以访问"光标"返回了汇总结果,因此您可以选择在大型结果集上进行改进:
var ids = [];
var cursor = db.collection.aggregate([
{ "$sort": {
"house_id": 1,
"rate": 1
}},
{ "$group": {
"_id": "$house_id",
"docId": { "$first": "$_id" },
"count": { "$sum": 1 }
}},
{ "$match": {
"count": { "$gt": 1 }
}}
]);
cursor.forEach(function(doc) {
ids.push( doc.docId );
if ( ids.length % 500 == 0 ) {
db.collection.remove({ "_id": { "$in": ids } });
ids = [];
}
});
if ( ids.length > 0 )
db.collection.remove({ "_id": { "$in": ids } });
或者对于具有该基本结构的任何语言的一般实现。
所以你并不完全是#34;管道"或者"查询"因为不支持这样的操作。但是$in
运算符是在这里高效组合的方式,以及聚合为您提供一种有效的方法来找到您的最低"结果
它通常应该比循环每个可能的更有效" house_id"使用.find()
以及.sort()
和.limit(1)
修饰符的值可能已经实现或在此处另有建议。
同样反对另有建议,你不会导致删除"所有"如果您刚刚将.limit(1)
添加到您的查找中(如未显示),您不知道是否只有一个结果,那么您的文档就是如此。而且您可能不想删除您唯一的文档。