Updating an object in a nested array in Mongoose - mongodb

Given the following schema
{
"_id" : ObjectId("55e0ecfa422d86f0a3b37b90"),
"username" : "Michael",
"hostedEvents" : [
{ "_id" : "1", "usersApplied" : [ ] }
],
"joinedEvents" : [
{ "confirmed" : false }
]
}
And I am trying to push into the usersApplied array the string "Lisa"
Right now I have a mongodb command that works but I want to do this in mongoose:
db.users.update({username:'Michael', "hostedEvents._id": "1"},
{$addToSet: {"hostedEvents.$.usersApplied": {"username":"Lisa"}}});
I tried to do it in mongoose this way:
Users.update({username:'Michael', "hostedEvents._id": "1"},
{$addToSet: {"hostedEvents.$.usersApplied": {"username":"Lisa"}}});
I am trying to follow the recommendation made here

I think you should use $push instead
Users.update({username:'Michael', "hostedEvents._id": "1"},
{$push: {"hostedEvents.$.usersApplied": {"username":"Lisa"}}});
That should work.

Related

Mongodb: How to create an entry in array if not present

I have a document structure like the following:
{
"_id" : ObjectId("58be819769f922b8427e7f10"),
"id" : "58be7a4cfc13ae51020002cc",
"source" : "facebook",
"source_id" : "b37f5e43-ea3f-46d2-b2b0-b8f55e923933",
"data" : [
{
"date" : "5/8/2016",
"topics" : [
"Vectorworks",
"Statistics",
"Flight Planning",
"HTK",
"Custom Furniture"
]
},
{
"date" : "7/22/2016",
"topics" : [
"FDR",
"NS2",
"Power Plants"
]
},
{
"date" : "12/23/2016",
"topics" : [
"LTV",
"MMS"
]
}
]
}
Now, If I want to append more topics to the date "12/23/2016", I can do that using:
db.revision.findOneAndUpdate({id: '58be7a4cfc13ae51020002cc', data: {$elemMatch: {date: '03/17/2017'}}}, {$push: {'data.$.topics': 'java lambda'}},{upsert: true})
But, how can I add a new object, to data array when the entry for a date is not present?
First insert an empty data doc for the required date field, if its not already present
db.revision.update( {id: '58be7a4cfc13ae51020002cc', "data.date" : {$ne : '03/17/2017' }} ,
{$addToSet : {"data" : {'date' : '03/17/2017'}} } ,
false , //<-- upsert
true ); //<-- multi
Then update the same using the update query as devised by you
db.revision.findOneAndUpdate({id: '58be7a4cfc13ae51020002cc', data: {$elemMatch: {date: '03/17/2017'}}}, {$push: {'data.$.topics': 'java lambda'}},{upsert: true})

How to count and paginate subdocument which is an object in mongodb

I have data saved in the following:
{
"_id" : ObjectId("57723b5e009793e8f3cfd1d7"),
"room" : "1003",
"inout" : {
"1" : [
"i1654",
"o1656",
"i1706",
"o1707",
],
"2" : [
"i1655",
"o1656",
"i1715",
"o1715"
],
"3" : [
"i1801"
]
}
}
how to count and paginate the subdocument "inout" which is an object?
thanks!!!
Actually, there is a small modification required in your JSON. The "inout" should be an array to use the below solution.
"$unwind" can be used here.
Modified JSON to define "inout" as array rather than Object:-
db.rooms_second.insertOne({
"_id" : ObjectId("57723b5e009793e8f3cfd1d7"),
"room" : "1003",
"inout" : [
{"1" : [
"i1654",
"o1656",
"i1706",
"o1707",
]},
{"2" : [
"i1655",
"o1656",
"i1715",
"o1715"
]},
{"3" : [
"i1801"
]}
]
});
Mongodb Query:-
In the resultset, the below query will give you one record for each element in the "inout" array.
db.rooms_second.aggregate([ { $unwind: "$inout" } ])
The pagination can be done based on the driver and API that you are using (i.e. MongoDB Java Driver etc.).

Using embedded documents in spring data aggregation

I have a MongoDB document like this example doc:
{
"_id" : "A",
"articleNumber" : "0123456",
"shopDependentProperties" :
{
"shop" : "DE",
"foo" : "foo",
"bar" : "bar"
}
}
and want to pull out the properties of shopDependentProperties, to have the following result
{
"_id" : "A",
"articleNumber" : "0123456",
"foo" : "foo",
"bar" : "bar"
}
In MongoDB Shell i can solve it this way:
db.test.aggregate(
[
{
$project:
{
_id : "$_id",
articleNumber : "$articleNumber",
foo:"$shopDependentProperties.foo",
bar:"$shopDependentProperties.bar"
}
}
]
)
But: In Spring Data MongoDB i can't extract the embedded document contents.
I tried many combinations, nothing worked. For example:
ProjectionOperation projection = Aggregation.project("_id");
projection.andExpression("shopDependentProperties.foo").as("foo");
projection.andExpression("shopDependentProperties.bar").as("bar");
System.out.println(projection.toDBObject(Aggregation.DEFAULT_CONTEXT));
will ignore the shopDependentProperties.shop stuff and just print out
{ "$project" : { "_id" : 1}}
Any suggestions?
Thx
Haven't tested this, but as of
http://docs.mongodb.org/manual/reference/operator/aggregation/project/
you specify included / excluded fields like this:
db.test.aggregate(
[
{
$project:
{
_id : "$_id",
articleNumber : 1,
"shopDependentProperties.foo": 1,
"shopDependentProperties.bar": 1
}
}
]
)
Further down they explain, how to include embedded documents in the projection result.
I know how to do it in MongoDB, the problem was about doing the same thing in Spring Data.
But it works the same way, why didn't I try that before?
Solution:
ProjectionOperation projection = Aggregation.project(
"brandName",
"$shopDependentProperties.foo",
"$shopDependentProperties.bar" );

Removing a (sub) array in MongoDB using $pull

So..I'm evaluating Mongodb for managing a bit of my JSON back end. I'm totally new to it and I had one problem that was just messy to do in code, so I thought — heck — let me check out to see if it's time to finally start using Mongo
I have a data structure that is approximately like this:
[
{
"_id" : ObjectId("526f59ee82f2e293f9833c54"),
"humans" : [
{
"serviceUsers" : [
{
"foo1" : "bar2",
"foo2" : "bar3"
},
{
"foo1" : "baz2",
"foo2" : "baz3"
}
]
}
]
}
]
And now I want to remove any serviceUsers array elements that have "foo1" equal to "baz2" so that ideally I would end up with this:
[
{
"_id" : ObjectId("526f59ee82f2e293f9833c54"),
"humans" : [
{
"serviceUsers" : [
{
"foo1" : "bar2",
"foo2" : "bar3"
},
]
}
]
}
]
I figured that $pull was the place to start. And I tried a bunch of contortions. If I'm in collection mytests, I tried
db.mytests.update({"humans.serviceUsers.foo1":"baz2"}, {$pull:{"humans.serviceUsers" : {"foo1":"baz2"}}}, {multi: true})
Which to my admittedly naive eye, seems like it should follow the $pull syntax:
db.collection.update( { field: <query> }, { $pull: { field: <query> } } );
Mongo doesn't complain. But it doesn't change the collection in any way, either.
I also tried
db.mytests.update({}, {$pull:{"humans.serviceUsers" : {"foo1":"baz2"}}}, {multi: true})
Which also failed.
Any suggestions are greatly appreciated.
Thus humans is also array, you should use positional $ operator to access serviceUsers array of matched humans element:
db.mytests.update({ "humans.serviceUsers.foo1" : "baz2" },
{ $pull: { "humans.$.serviceUsers" : { "foo1": "baz2" }}});

Mongodb array structure

Theres something here I can't quite figure out.
When I attempt to query an object with several fields I yield no results. The object structure looks like this:
{
"_id" : ObjectId("4d8b55f017a7303b0b000000"),
"title" : "Apollo",
"body" : "A spaceflight mission to the moon",
"tags" : [ [ "moon", "space", "nasa", "mission" ] ]
}
This is my query:
db.test.find({ tags: { $all: ['moon', 'mission'] } })
However I do get result by creating a new object with a single field:
{
"_id" : ObjectId("4d8b9e5935037b3c8228709c"),
"tags" : [ "apple", "banana", "pear" ]
}
... with the same query as the one above.
['tags'] isn't nested inside any other array, so why does it not return my search queries? Please enlighten me.
Sincerely,
Why
Why are you using a nested array
"tags" : [ [ "moon", "space", "nasa", "mission" ] ]
here?
This does not make any sense.
db.test.find({ tags: { $all: [ ['moon', 'mission'] ] } })