我对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的最低速率的文档?
发布于 2014-04-25 22:11:34
不幸的是,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;
})这是目前最好的办法。
发布于 2014-06-02 02:25:39
虽然这里的基本答案是您需要循环结果,但通过一次命中获得所有“最小值”文档,您可能会做得更好。聚合框架对此非常有用,因为您可以将$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 } });或基本结构的任何语言的一般实现。
因此,您不完全是“管道”或“子查询”结果,因为这样的操作是不受支持的。但是,$in运算符是在这里高效组合的方法,也是聚合的方法,为您找到“最低”结果提供了一种有效的方法。
通常,它应该比在这里使用.find()以及.sort()和.limit(1)修饰符循环所有可能的“.sort()”值更有效。
另外,与其他建议相反,您将不会删除“所有”您的文档,甚至可能是这样,如果您只是将.limit(1)添加到您的查找中(如未显示的那样),即您不知道是否只有一个结果。而且您可能不想删除您唯一的文档。
https://stackoverflow.com/questions/23301805
复制相似问题