0

I have a collection with an entry that looks like the below.

{
"_id" : ObjectId("57f6021caa3e1d3ee099af0d"),
"user" : "JBL123",
"name" : "Joe Bloggs",
"monthly_activity" : [
    {
        "month" : "September2016",
        "status" : "active",
        "daily_stats" : [
            {
                "date" : "27/SEP/2016",
                "stats" : [ 
                    {
                        "category":
                        "stat1":
                        "stat2":
                    },
                    {
                        "category":
                        "stat1":
                        "stat2":
                    }
                ]
            },
            {
                "date" : "28/SEP/2016",
                "stats" : [ 
                    {
                        "category": ...
                        "stat1": ...
                        "stat2": ...
                    },
                    {
                        "category": ...
                        "stat1": ...
                        "stat2": ...
                    }
                ]
            },
        ],
        "extra_fields": ....
    }
]
}

I want to insert stats for a new category on a specified date.

I've tried the below

mdb.getCollection("users").updateOne(new Document("user", "JBL123").append("monthly_activity.daily_stats.date", "27/SEP/2016"),
    new Document("$addToSet", (new Document("monthly_activity.daily_stats.$.stats",
        new Document("category",cat)
            .append("stat1", s1)
            .append("stat2", s2)))));

But it doesn't like using dot notation to access the subarray of an array. I get the following error...

Exception in thread "main" com.mongodb.MongoWriteException: can't append to array using string field name [daily_stats]

Is this possible from a single update?

1 Answer 1

1

monthly_activity is an array, so you need to use positional value/operator refer an element.

To identify the update field, you can use the positional operator $ only once , even if the field is nested within arrays (a current limitation). That would require you to know the position of the other arrays elements in the hierarchy. In this case, you will need to know the position of either monthly_activity or daily_stats.

If you have the position of the monthly_activity element (say 0), then you update field can be identified by monthly_activity.0.daily_stats.$.stats.

The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, but how do I get that position? Ideally I would be searching monthly_activity for where month="September2016" and using that as the pointer, but can this be incorporated into the original filter?
something like mdb.getCollection("users").updateOne(new Document("user", "JBL123").append("monthly_activity.daily_stats.date", "27/SEP/2016").append("monthly_activity.month","September2016", new Document("$addToSet", (new Document("monthly_activity.$.daily_stats.$.stats", new Document("category",cat) .append("stat1", s1) .append("stat2", s2)))));
@bw12345 Updated my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.