简体   繁体   中英

Mongodb: insert an object to the array, only if an element of that object in unique

I have this collection. I am trying to add object(item = {label: "Chrome", value: "chrome"}) to the array only if the value is unique, ie insert the whole object, item in the array foo only if array foo doesn't have any other object with the same value as item , using one MongoDB operation

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

i don't think $addToSet supports duplicate detection of object fields like you want. however you could do it like this:

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

first you match the parent object by id + that it doesn't contain "firefox" as the value in the foo object array. then you specify a $push to add your new object to the foo array. that way, no duplicates will be created in the foo array.

not sure what your coding language is but here's the c# code that generated the above mongo query in case anybody's interested:

 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(); } } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM