根据给定文档的值是否在数组中,使用布尔值创建一个新字段

时间:2019-10-11 02:14:29

标签: mongodb aggregation-framework

鉴于我有一组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") ] }

我想在下面的聚合管道中创建一个新字段,如果给定的文档ID在上述ID数组中不存在,则求值为1-1。实际上,我将能够按布尔值对文档进行排序。乍看起来,'$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 },

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

1 个答案:

答案 0 :(得分:0)

$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 }  }
])