【问题标题】:Arrgregate $out mongodb insert for $out failed duplicate ErrorArrgregate $out mongodb insert for $out failed duplicate Error
【发布时间】:2018-07-09 18:45:59
【问题描述】:

Query1:我试图使用 mongodb Aggregate $lookup 将两个集合与两个集合的选定字段组合如下

 db.col1.aggregate([
   {
       $lookup: {
          from: "col2",
          localField: "field1",    
          foreignField: "field2", 
          as: "user"
       }
   },
   {
       $unwind:"$user"
   },
   { $project: { "userfield": "$user.field",col1field:1 } },
  {$out:"new_col"}
 ])


**Error:**

*"errmsg" : "insert for $out failed: { connectionId: 4275, err: 'E11000 duplicate key error collection: db.tmp.agg_out.1 index: _id_ dup key: { : ObjectId('5b16305d145a5117552836ec') }', code: 11000, n: 0, ok: 1.0 }",
**"code" : 16996***

----------

Query2:在投影中我添加了 _id:0

 db.col1.aggregate([
   {
       $lookup: {
          from: "col2",
          localField: "field1",    
          foreignField: "field2", 
          as: "user"
       }
   },
   {
       $unwind:"$user"
   },
   { $project: { "userfield": "$user.field",col1field:1 ,**_id:0**} },
  {$out:"new_col"}
 ])

**Error:**
no error and no output 

【问题讨论】:

    标签: mongodb mongodb-query


    【解决方案1】:

    您的$lookup 阶段只是在user 字段中返回多个条目,然后将这些条目展平为具有相同_id 值的各个子文档。您可以通过将$out 阶段替换为$match 来验证这一点:

    db.col1.aggregate([{
        $match: { _id: ObjectId('5b16305d145a5117552836ec') }
    }
    

    这里的关键是了解$unwind 的工作原理。假设您有以下文档:

    {
        _id: 1,
        users: [ 'a', 'b' ]
    }
    

    一旦你$unwind这个你会得到以下两个文件:

    {
        _id: 1,
        users: 'a'
    },
    {
        _id: 1,
        users: 'b'
    }
    

    因此,对于两个不同的文档,您会得到相同的 _id 值!

    现在,当您在投影中指定 _id: 0 时,您会从所有文档中删除 _id 字段,这将导致 MongoDB 自动创建新的 _ids,这当然会起作用。

    【讨论】:

    • 谢谢,但我知道这一切,所以你有没有其他解决方案来完成这项工作。
    • 如果你告诉我你到底想达到什么目标,那么我很乐意为你的问题想出一个解决方案。
    • 我要存储查询输出
    【解决方案2】:

    好的,重复的 id 解释。另外,如果你想保留user._id,在你上一个项目阶段添加id:"$_id"

    但是对于 _id:0 的第二个查询,'没有错误和没有输出是什么意思:

    • 如果您的查询运行良好,结果将插入一个名为“new_col”的新集合中,因此您必须运行 db.getCollection("new_col").find({});检索它们。 $out 阶段的控制台中没有任何内容!
    • 如果您的 new_col 集合不存在或为空:无论 $out 阶段如何,您的查询都不会返回任何内容。在这种情况下,请提供 col1 和 col2 文档示例

    ---编辑--- 有了这些数据:

    col1 : 
    { 
    "_id" : 1.0, 
    "field1" : "a", 
    "field2" : "b"
    }
    col2 : 
    { 
    "_id" : 1.0, 
    "field1" : "a", 
    "field2" : "c"
    }
    

    实现您需要的正确查询如下:

    db.col1.aggregate(
    [
        // Stage 1
        {
            $lookup: {
                 from: "col2",
                      localField: "field1",    
                      foreignField: "field1", 
                      as: "user"
            }
        },
        // Stage 2
        {
            $unwind: {
                path : "$user",
    
            }
        },
        // Stage 3
        {
            $project: {
               "userfield": "$user.field1",field1:1
            }
        },
    
    ]
    );
    

    将输出:

    { 
        "_id" : 1.0, 
        "field1" : "a", 
        "userfield" : "a"
    }
    

    【讨论】:

    • 我不想保留上一个项目的 _id 字段,
    • @mathPen 1.我知道不会有 $out 的控制台输出,但是当我运行“显示集合”命令时,新集合不会显示在集合列表中。 2.如果我在聚合查询中不使用管道 $out,则给出一个输出,Collections Schema: col1: {_id:1, field1:'a' field2:'b'} col2: {_id:2, field1:' a' field2:'c'}
    • 使用这些数据,您的查询将不会返回任何内容!您正在 col1.field1 和 col2.field2 之间进行查找,但这些值是不同的。因此,在查找“用户”字段之后是一个空数组,并且在展开之后你不会得到更多结果。用完整的正确查询编辑我的答案。
    猜你喜欢
    • 2017-03-31
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    相关资源
    最近更新 更多