首页 > 解决方案 > 根据给定文档的值是否在数组中创建具有布尔值的新字段

问题描述

鉴于我有一组 id,例如:

db.calendars.aggregate([
   { '$match' : { _id: { '$in' : filtered_ids } }  },
   { '$group' : { _id: null, ids: { '$push' : '$_id' }  }  },
   { '$project' : {_id: 0, ids: 1} }
])
{ "ids" : [ ObjectId("5d9ce5d73ed1492058a3a2df"), ObjectId("5d9ce88e3ed14921b6e1a9f1"), ObjectId("5d9ce88e3ed14921b6e1a9f3") ] }

我想在下面的聚合管道中创建一个新字段,该字段评估给定的文档 ID1是否-1存在于上述 ID 数组中。实际上,我将能够按布尔值对文档进行排序。乍一看,'$cmp'运营商似乎很合适。

db.calendars.aggregate([
  { '$addFields' : { 'shared' : { '$cmp' : ['$_id', [ ObjectId("5d9ce5d73ed1492058a3a2df"), ObjectId("5d9ce88e3ed14921b6e1a9f1"), ObjectId("5d9ce88e3ed14921b6e1a9f3") ] ] } },
  { '$sort' : { shared: -1 }  }
])

但是 '$cmp' 运算符只比较了这两个值。它不会像 '$in' 那样比较一个值是否在一组值中。我的问题是如何在比较值时合并“$in”要求。

预期结果如下所示:

{ '_id' : Object('...'), name: 'New event', shared: -1 },
{ '_id' : Object('...'), name: 'Another event', shared: -1 },
{ '_id' : Object('...'), name: 'Cool event', shared: 1 },
{ '_id' : Object('...'), name: 'Wow, an event', shared: 1 },

您看到文档是如何按新字段排序的吗?

标签: mongodbaggregation-framework

解决方案


$in返回一个布尔值,因此您可以使用$cond设置1-1

db.calendars.aggregate([
    {
        $addFields: {
            shared: {
                $cond: [ { $in: [ "$_id", [ ObjectId("5d9ce5d73ed1492058a3a2df"), ObjectId("5d9ce88e3ed14921b6e1a9f1"), ObjectId("5d9ce88e3ed14921b6e1a9f3") ] ] }, 1, -1 ]
            }
        }
    },
    { '$sort' : { shared: -1 }  }
])

$sort如果您想简化,或者在布尔值上运行:

db.calendars.aggregate([
    {
        $addFields: {
            shared: {
                $in: [ "$_id", [ ObjectId("5d9ce5d73ed1492058a3a2df"), ObjectId("5d9ce88e3ed14921b6e1a9f1"), ObjectId("5d9ce88e3ed14921b6e1a9f3") ] ] 
            }
        }
    },
    { '$sort' : { shared: -1 }  }
])

推荐阅读