使用 $merge 来自 mongo 聚合管道的错误

时间:2021-06-24 15:38:39

标签: mongodb indexing aggregation-framework

我有一个带有 _id 和 observables 数组的简单集合 alert

例如

{
  _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

1 个答案:

答案 0 :(得分:1)

您可以但不需要需要创建该索引,您需要的是生成唯一的 _id 值。

由于您要合并到现有集合中而不是输出到新集合中,我建议您创建一个由 _idobservables 字段串联构建的 _id 字段

例如使用 $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"
    }
  }
])

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