【问题标题】:Find and delete duplicate Entries in an embedded Array查找和删除嵌入式数组中的重复条目
【发布时间】:2015-06-04 19:27:47
【问题描述】:

我在我的 MongoDB 中得到了下面图解的 JSON。我收到了几百个条目。问题是其中一些在嵌入式数组中有多个条目。在此图中,不允许使用数组类型的 entry_2 和以下 entry_2 对象。我想删除类型数组名称值为“entry_2”的两个对象之一。

{   
   "id": null,
   "name": "",
   "array" [
       {
             "name": "entry_1"
       },
       {
             "name": "entry_2"

       },
       {
             "name": "entry_2"

       },
       {
             "name": "entry_3"

       }
   ]
}

因此,我的 JSON 在 Query 之后应该如下所示:

{   
   "id": null,
   "name": "",
   "array" [
       {
             "name": "entry_1"
       },
       {
             "name": "entry_2"

       },
       {
             "name": "entry_3"

       }
   ]
}

我尝试浏览 SO 并阅读 http://docs.mongodb.org/manual/tutorial/query-documents/#exact-match-on-the-embedded-document,但找不到解决方案。


-- 编辑--

我必须使用选项 { allowDiskUse: true } 并且不知道如何在查询中实现它。此外,我尝试将查询调整为我的特定用例,其中我得到了以下结构:

{
    "_id": {
        "$oid": "556ccf6f59bbda5ea20a8884"
},
"id": 1159,
"description": "Cheese, goat, soft type",
"tags": [],
"manufacturer": "",
"group": "Dairy and Egg Products",
"portions": [
    {
        "unit": "oz",
        "grams": 28.35,
        "amount": 1
    }
],
"nutrients": [
    {
        "description": "Protein",
        "group": "Composition",
        "value": 18.52,
        "units": "g"
    },
    {
        "group": "Composition",
        "value": 21.08,
        "units": "g",
        "description": "Total lipid (fat)"
    },
    {
        "description": "Protein",
        "group": "Composition",
        "value": 18.52,
        "units": "g"
    }
    ]
}

根据我尝试过的以下答案:

var pipeline = [
    {
        "$unwind": "$nutrients"
    },
    {
       "$group": {
           "_id": "$_id",
           "id": { "$first": "$id" }
           "description": { "$first": "$description" },
           "tags" : { "$first": "$tags" },
           "manufacturer" : { "$first": "$manufacturer" },
           "group" : { "$first": "$group" },     
           "portions" : { "$first": "$portions" },
           "nutrients": {
               "$addToSet": "$nutrients"
           }        
       }
    }
],
options = { "allowDiskUse": true };
db.collection.aggregate(pipeline, options);

我收到错误消息:“意外字符串”。 我想这与“_id”对象和“tags”数组有关。

【问题讨论】:

  • 您收到错误是因为您的管道在$group 运算符表达式中的"id": { "$first": "$id" } 表达式之后缺少逗号,

标签: mongodb


【解决方案1】:

尝试聚合框架,特别是 $addToSet 运算符,accumulator operator 仅在 $group 阶段可用。这将添加一个所有唯一值的数组,这些唯一值是通过将表达式应用于一组文档中的每个文档而产生的,这些文档按键共享同一组:

db.collection.aggregate([
    {
        "$unwind": "$array"
    },
    {
       "$group": {
           "_id": "$_id",
           "array": {
               "$addToSet": "$array"
           },
           "name": { "$first": "$name" },
           "id": { "$first": "$id" }
       }
    }
])

输出是带有对象的所需数组:

/* 0 */
{
    "result" : [ 
        {
            "_id" : ObjectId("5570a775d41ac325b8cb9a5f"),      
            "id": null,
            "array" : [ 
                {
                    "name" : "entry_3"
                }, 
                {
                    "name" : "entry_2"
                }, 
                {
                    "name" : "entry_1"
                }
            ],
            "name" : ""
        }
    ],
    "ok" : 1
}

-- 编辑--

要将allowDiskSpace 设置为true,aggregate() 方法允许为此类选项添加第二个参数。例如,使用上述管道,您可以执行以下操作:

var pipeline = [
        {
            "$unwind": "$array"
        },
        {
           "$group": {
               "_id": "$_id",
               "array": {
                   "$addToSet": "$array"
               },
               "name": { "$first": "$name" },
               "id": { "$first": "$id" }
           }
        }
    ],
    options = { "allowDiskUse": true };

db.collection.aggregate(pipeline, options);

【讨论】:

  • 我必须将 allowDiskSpace 设置为 true。但我不确定如何在上述查询中执行此操作。
  • @user1772306 我已更新我的答案以包含此内容。
  • @chirdam 谢谢,我相应地更新了问题。我想我已经接近解决方案了。谢谢大家的帮助!
  • 这会删除重复记录吗?还是只是重复选择了第一个?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
  • 2023-03-11
  • 1970-01-01
  • 2019-12-14
  • 1970-01-01
相关资源
最近更新 更多