boilers222
boilers222

Reputation: 1989

How do I add an array of elements in MongoDB to an array in an existing document?

In MongoDB, I'm trying to write a query to add elements from an array to an existing document, but instead of adding the elements as objects:

property: ObjectID(xxx)

the elements are getting added as just

ObjectID(xxx)

Forgive me if I get the terminology wrong. I'm completely new to MongoDB; I normally only work with relational databases. How do I properly add these new elements?

I have a collection called auctions which has two fields: ID and properties. Properties is an array of objects named property. Here's an example with two auction documents:

** I changed the object IDs to make them easier to reference in our discussion

Collection db.auctions
{
    "_id" : ObjectId("abc"),
    "properties" : [
        {
            "property" : ObjectId("prop1")
        }, 
        {
            "property" : ObjectId("prop2")
        }, 
        {
            "property" : ObjectId("prop3")
        }]
}
{
    "_id" : ObjectId("def"),
    "properties" : [
        {
            "property" : ObjectId("prop97")
        }, 
        {
            "property" : ObjectId("prop98")
        }]
}

I want to add 3 new properties to auction "abc". How do I do this?

Here's is what I tried:

I have an array of properties that looks like this:

Array PropsToAdd
[
    ObjectId("prop4"), 
    ObjectId("prop5"), 
    ObjectId("prop6")
]

I wrote an update query to push these properties into the properties array in auctions:

db.auctions.update(
    {"_id": "abc"}
    ,
    { $push: { properties: { $each: PropsToAdd } } } 
);

This query gave the result below. Notice that instead of adding elements named property with a value from my array, it's just added my values from my array. I obviously need to add that "property" part, but how do I do that?

Collection db.auctions (_id "abc" only)
    {
    "_id" : ObjectId("abc"),
    "properties" : [
        {
            "property" : ObjectId("prop1")
        }, 
        {
            "property" : ObjectId("prop2")
        }, 
        {
            "property" : ObjectId("prop3")
        }, 
        ObjectId("prop4"), 
        ObjectId("prop5"), 
        ObjectId("prop6"), 
        ObjectId("prop7")]
}

The result I'm looking for is this:

Collection db.auctions (_id "abc" only)
{
    "_id" : ObjectId("abc"),
    "properties" : [
        {
            "property" : ObjectId("prop1")
        }, 
        {
            "property" : ObjectId("prop2")
        }, 
        {
            "property" : ObjectId("prop3")
        }, 
        {
            "property" : ObjectId("prop4")
        },
        {
            "property" : ObjectId("prop5")
        },         
        {
            "property" : ObjectId("prop6")
        } 
}

Here is some further information on that array of properties I'm adding. I get it from running these queries. Perhaps one of them needs changed?

This query gets an array of current properties:

var oldActiveProperties = db.properties.distinct( "saleNumber", { "active": true, "auction": ObjectId("abc") } );

Then those results are used to find properties in the new file that weren't in the old file:

var PropsToAdd = db.newProperties.distinct(
    "_id"
    , { "saleNumber": { "$nin": oldActiveProperties }, "active": true}
);

The resulting array is what I need to add to the auctions collection.

Upvotes: 2

Views: 2182

Answers (1)

chridam
chridam

Reputation: 103475

Use the JavaScript's native map() method to map the array into an array of documents. The following shows this:

var PropsToAdd = db.newProperties.distinct("_id", 
    { "saleNumber": { "$nin": oldActiveProperties }, "active": true}
).map(function (p) { return { property: p }; });

db.auctions.update(
    {"_id": "abc"},
    { $push: { "properties": { "$each": PropsToAdd } } } 
);

Upvotes: 3

Related Questions