1

Consider the following object:

var child = {
    title: "Shoes",
    active: true,
    sort: 1
}

And the following update:

    db.Category.update(
        { _id: this._id },
        { $addToSet: { children: child }}, function(error) {
            if (error) {
                console.log(error.reason);
            } else {
                console.log("success");
            }
        }
    );

Is there a way to add a more specific condition on this? Basically, I only want an item added to the array if it doesn't already exist, but Mongo determines this by all the properties of the child.

I basically want the update to fail if children.title exists, in uppercase, lowercase, etc.

So if I have a document such as:

{
    title: "Clothing",
    active: true,
    sortorder: 1,
    children: [
        {
            title: "Shoes",
            active: true,
            sortorder: 1
        }
    ]
}

I want any kind of addition to this array to fail if the title: "Shoes" exists... shoes, ShoEs, SHOES, should all fail. Or, regardless if the other properties of this child are different such as active, or sort order, I want it to fail based on just the title.

Is there a conditional method I'm missing?

halfer
  • 19,824
  • 17
  • 99
  • 186
user1447679
  • 3,076
  • 7
  • 32
  • 69

1 Answers1

0

Regular expression match can help to do this.

var child = {
    title: "Shoes",
    active: true,
    sort: 1
}

Method 1:

db.Category.update({
    "_id" : this._id, 
    "children.title" : {
        $not : /^shoes$/i
    }
}, {
    $push : {
        children : child
    }
}, funcCallback);

Method 2:

var title = "Shoes";
var regexp = "^(?!" + title + "$)";

db.Category.update({
    "_id" : this._id, 
    "children.title" : {
        $regex : regexp,
        $options : "i"
    }
}, {
    $push : {
        children : child
    }
}, funcCallback);
Wizard
  • 4,341
  • 1
  • 15
  • 13
  • I'm getting strange behavior on the regex and I'm not sure why. I'm trying to concatenate it like var regex = "/^" + title + "$/i"; and then using the variable regex for the $not, but it isn't working. Another thing I noticed that was crazy is... if I manually type in $not : "shoes" it matches any case comparison and works, but if I use var word = "shoes" and use the variable in the $not, it doesn't work... Weird. – user1447679 Oct 01 '14 at 16:28
  • Also, thank you for your answer. Trying to get it to work. – user1447679 Oct 01 '14 at 16:29
  • @user1447679, `/^shoes$/i` is an integrity and can not produced by the concatenation of strings. If you use `$regex` operator, `$not` is prohibited, according to MongoDB manual. – Wizard Oct 02 '14 at 06:36