【问题标题】:MongoDB: Find the minimum element in array and delete itMongoDB:找到数组中的最小元素并将其删除
【发布时间】:2012-10-31 08:42:34
【问题描述】:

我在 MongoDB 中有一个文档,其中一个看起来像这样:

{
"_id" : 100,
"name" : "Something",
"items" : [
    {
        "item" : 47,
        "color" : "red"
    },
    {
        "item" : 44,
        "color" : "green"
    },
    {
        "item" : 39,
        "color" : "blue"
    }
]
}

在每个文档中,我都需要找到最小的项目并将其删除。所以应该是这样的:

{
"_id" : 100,
"name" : "Something",
"items" : [
    {
        "item" : 47,
        "color" : "red"
    },
    {
        "item" : 44,
        "color" : "green"
    }
]
}

看起来应该在这里使用findAndModify 函数,但我不能再继续了。

如何找到数组中的最小元素并删除?

我正在使用 MongoDB 和 Pymongo 驱动程序。

【问题讨论】:

  • 哈哈,你在上 10gen 课程吗?第 3-2 周?

标签: python mongodb pymongo


【解决方案1】:

如果您不限于将查询放在一个步骤中,您可以尝试:

步骤 1) 使用 $unwind 和 $group 运算符的聚合函数来找到每个文档的最小项目

myresults = db.megas.aggregate( [ { "$unwind": "$items" },  
    {"$group": { '_id':'$_id' , 'minitem': {'$min': "$items.item" } } } ] )

步骤 2) 循环遍历结果并 $pull 从数组中的元素

for result in myresults['result']:
    db.megas.update( { '_id': result['_id'] }, 
        { '$pull': { 'items': { 'item': result['minitem'] } } } )

【讨论】:

  • 如果您想过滤红色或绿色项目的最小值,您可以在聚合语法中添加 {'$match': {"items.color": "red"} }。跨度>
  • 我通过 mongo shell 添加了以下代码 for(i=0; i
  • 我能够运行他的第一个查询..我无法执行更新操作..我使用 for(i=0;i
  • 我必须删除 ['result'] 才能使其工作。代码如下: for result in myresults: db.megas.update( { '_id': result['_id'] }, { '$pull': { 'items': { 'item': result['miniitem '] } } } )
【解决方案2】:

请找到我用纯 javascript 编写的解决方案。它应该直接通过 MongoDb shell 工作

cursor = db.students.aggregate(
[{ "$unwind": "$items" }, 
 { "$match": { "items.color": "green"}},
 { "$group": {'_id': '$_id', 'minitem': {
                '$min': "$items.item"
            }
        }
    }

]);

cursor.forEach(
function(coll) {
    db.students.update({
        '_id': coll._id
    }, {
        '$pull': {
            'items': {
                'item': coll.minitem
            }
        }
    })
})

【讨论】:

  • 匹配语句是可选的。但对于进一步缩小数组中的选择范围很有用
  • 只是添加到上面的答案,您还可以查看 Javascript 的for... ofdeveloper.mozilla.org/en/docs/Web/JavaScript/Reference/…
  • 以上将一次获取 20 条记录如何获取所有记录并更新它们?
【解决方案3】:

Mongo 4.4 开始,$function 聚合运算符允许应用自定义 javascript 函数来实现 MongoDB 查询语言不支持的行为。

再加上对Mongo 4.2 中的db.collection.update() 的改进,可以接受聚合管道,允许根据自己的值更新字段,

我们可以以语言不允许的方式操作和更新数组:

// {
//   "name" : "Something",
//   "items" : [
//     { "item" : 47, "color" : "red"   },
//     { "item" : 39, "color" : "blue"  },
//     { "item" : 44, "color" : "green" }
//   ]
// }
db.collection.update(
  {},
  [{ $set:
    { "items":
      { $function: {
          body: function(items) {
            var min = Math.min(...items.map(x => x.item));
            return items.filter(x => x.item != min);
          },
          args: ["$items"],
          lang: "js"
      }}
    }
  }],
  { multi: true }
)
// {
//   "name" : "Something",
//   "items" : [
//     { "item" : 47, "color" : "red"   },
//     { "item" : 44, "color" : "green" }
//   ]
// }

$function 接受 3 个参数:

  • body,即要应用的函数,其参数是要修改的数组。这里的函数只是首先从数组中找到最小的item,然后将filter 找出来。
  • args,它包含来自记录的字段,body 函数将其作为参数。在我们的例子中,"$items"
  • lang,这是编写 body 函数的语言。目前只有js 可用。

【讨论】:

  • 我会说在接下来的两个月内的某个时间。这是当前的changelog
  • 非常棒的功能!
猜你喜欢
  • 1970-01-01
  • 2017-12-09
  • 2017-12-22
  • 2015-06-12
  • 2013-03-04
  • 1970-01-01
  • 2013-01-06
  • 1970-01-01
相关资源
最近更新 更多