首页 > 解决方案 > Mongodb:仅当该对象的元素唯一时才将对象插入数组

问题描述

我有这个收藏。我试图将 object(item = {label: "Chrome", value: "chrome"}) 添加到数组中,只有当它value是唯一的时,即插入整个对象,只有当数组item没有任何其他时与 具有相同值的对象,使用一个 MongoDB 操作foofooitem

foo=[{label:"IE",value:"ie"},{label:"Firefox",value:"firefox"}]

标签: node.jsmongodbmongodb-3.6

解决方案


我不认为 $addToSet 支持您想要的对象字段的重复检测。但是你可以这样做:

db.bars.update(
    {
        "_id": ObjectId("5d3421a6a0100c1e083356e1"),
        "foo": {
            "$not": {
                "$elemMatch": {
                    "value": "firefox"
                }
            }
        }
    },
    {
        "$push": {
            "foo": {
                "label": "Fake Fox",
                "value": "firefox"
            }
        }
    }
)

首先,您通过 id + 匹配父对象,它不包含“firefox”作为 foo 对象数组中的值。然后您指定 a$push将您的新对象添加到 foo 数组。这样,不会在 foo 数组中创建重复项。

不确定您的编码语言是什么,但如果有人感兴趣,这里是生成上述 mongo 查询的 c# 代码:

using MongoDB.Entities;
using System.Linq;

namespace StackOverflow
{
    public class Program
    {
        public class bar : Entity
        {
            public item[] foo { get; set; }
        }

        public class item
        {
            public string label { get; set; }
            public string value { get; set; }
        }

        private static void Main(string[] args)
        {
            new DB("test");

            var bar = new bar
            {
                foo = new[]
                {
                    new item { label = "IE", value = "ie"},
                    new item { label = "FireFox", value = "firefox" }
                }
            };
            bar.Save();

            var chrome = new item { label = "Chrome", value = "chrome" };
            var firefox = new item { label = "Fake Fox", value = "firefox" };

            DB.Update<bar>()
              .Match(b => 
                     b.ID == bar.ID && !b.foo.Any(i => i.value == chrome.value))
              .Modify(x => x.Push(b => b.foo, chrome))
              .Execute();

            DB.Update<bar>()
              .Match(b => b.ID == bar.ID && !b.foo.Any(i => i.value == firefox.value))
              .Modify(x => x.Push(b => b.foo, firefox))
              .Execute();
        }
    }
}


推荐阅读