mongodb 带有$merge的mongo聚合管道出错

ukdjmx9f  于 2022-11-03  发布在  Go
关注(0)|答案(2)|浏览(168)

我有一个简单的集合 alert with _id和observables数组
例如:

{
  _id: '60d496b2d08d5f0630dea368',
  observables: ['10d496b2d08d5f0630dea368', '20d496b2d08d5f0630dea368'],
}

我创建了一个查询来创建新的集合,而不使用如下格式的数组:

{
  _id: <default id>,
  alertId: '60d496b2d08d5f0630dea368',
  observableId: '10d496b2d08d5f0630dea368',
{
  _id: <default id>,
  alertId: '60d496b2d08d5f0630dea368',
  observableId: '20d496b2d08d5f0630dea368',
}

此外,为了防止重复,还创建了唯一索引

collection.createIndex({ observableId: 1, alertId: 1 }, { unique: true });

我的问题是:

db.collection.aggregate([
  {
    "$unwind": "$observables"
  },
  {
    "$project": {
      _id: 0,
      observableId: "$observables",
      alertId: "$_id"
    }
  },
  {
    "$merge": {
      into: {
        db: "some-db",
        coll: "some-coll"
      },
      on: [
        "observableId",
        "alertId"
      ]
    }
  }
])

结果出现错误*MongoError:找不到索引来验证联接字段是否唯一
但是索引已经创建了,所以有什么办法可以修复这个错误吗?
链接到mongoplayground

afdcj2ne

afdcj2ne1#

您可以但不需要创建该索引,您需要的是生成一个唯一的_id值。
由于要合并到现有集合中,而不是输出到新集合中,因此建议创建一个_id字段,该字段由_idobservables字段串联而成
例如使用$toString$concat

"_id": {$concat: [{$toString: "$_id"}, "-", {$toString: "$observables"}]}

这样,您就有了一个可重复的过程,其中运行两次将得到相同的_id值。
您可以使用以下方法合并到现有集合中:

{ $merge: { into: ..., on: "_id", whenMatched: "keepExisting", whenNotMatched: "insert" } }

完整示例:

db.collection.aggregate([
  {
    "$unwind": "$observables"
  },
  {
    "$project": {
      _id: {$concat: [
        {$toString: "$_id"},
        "-",
        {$toString: "$observables"}
      ]},
      observableId: "$observables",
      alertId: "$_id"
    }
  },
  {
    "$merge": {
      into: {db: "some-db", coll: "some-coll"},
      on: "_id"
    }
  }
])

关于您实现它的方式,我猜测索引位于错误的数据库或集合上,即不在输出集合上。

zphenhs4

zphenhs42#

问题出在定序中。
索引排序规则和查询(在我的例子中是db.collection.aggregate)应该具有相同的排序规则

相关问题