根据另一个收集字段值设置一个MongoDB收集字段值

时间:2020-07-23 16:05:01

标签: mongodb

我有2个这样的收藏集:

//collection1
[{
    Name: 'abc'
},
{
    Name: 'def'
}]

// collection2
[{
    Name: 'abc'
    PresentInCollection1: '' // this field should be true since collection2.Name exists in collection1.Name
},
{
    Name: 'xyz'
    PresentInCollection1: '' // this field should be false since collection2.Name does not exists in collection1.Name
}]

collection2.PresentInCollection1collection2.Name匹配时,我想将$set的值collection1.Name设置为true。这是我尝试过的:

db.stocks.update({}, [{
    $lookup: {
      from: 'collection1',
      localField: 'Name',
      foreignField: 'Name',
      as: 'Match',
    },
  },
  {
    $set: {
      PresentInCollection1: {
        $cond: [{
            $eq: ["Name", "$Match.Name"]
          },
          true,
          false
        ]
      },
    },
  },
]);

它引发错误:

"$lookup is not allowed to be used within an update"

另一种方法是updating documents iteratively,但我想一次完成。我正在考虑MongoDB的$map-$reduce,但无法想到该查询:)

1 个答案:

答案 0 :(得分:1)

我会尝试使用$ addFields阶段而不是$ set。您基本上会在另一个集合中执行查找,然后要添加一个指定“匹配”数组长度的字段。然后,您将执行另一个$ addFields阶段,并添加所需的'PresentInCollection1'字段,如果数组的大小大于0,则将其设置为true。如果数组的大小小于或等于0,则将其设置为等于为假。

类似这样的东西(很抱歉,如果格式错误,我无权使用格式化程序或代码编辑器):

db.stocks.aggregate([{
    $lookup: {
      from: 'collection1',
      localField: 'Name',
      foreignField: 'Name',
      as: 'Match',
    },
  },
  {'$addFields': {
      'matchLen': {'$size': '$Match'}
    }
  },
 {'$addFields': {
     PresentInCollection1 : {'$cond':{ 
       'if': {$gt: ['$matchLen', 0]},
       'then': true,
       'else': false
        }
      }
    }
  },
 {'$unset': 'matchLen'}
]);

如果您希望文档出现在新集合中,则还需要最后使用out阶段。 (我没有包含它,因为我不确定您是否需要它)

也许有人可以找到更好的解决方案,但这只是我脑海中浮现的一个解决方案。