在嵌入式阵列中查找和删除重复的条目

时间:2015-06-04 19:27:48

标签: mongodb

我在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在查询后应如下所示:

{   
   "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”对象和“标签”数组有关。

1 个答案:

答案 0 :(得分: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);