I have a mongoDB record like the below mentioned-
{
"d": {
"education": [
{
"school": { "name": "one", "id": "1" }
},
{
"school": { "name" : "two", "id" : "2" }
}
]
}
}
now I am running a mongo query to fetch all the school name I have in my record, which is like this-
db.test.find({},{"d.education.0.school.name":"1"})
but the result is not what I am looking for, it is giving empty-
{
"_id": ObjectId("5722385b964f6cb39d49f875"),
"d" : { "education" : [ { }, { } ] }
}
I am hoping to get result something like this-
{
"_id": ObjectId("5087c96338aeb0538a832574"),
"d": {
"education": [
{
"school": { "name" : "one" }
}
]
}
}
The name of the school from first record of the school array. Please help!
Try This:
db.test.aggregate([{"$project":
{"d.education.school.name":true}},
{$unwind:"$d.education.school"},
{"$limit":1}])
Related
Consider a collection client with the following documents:
[
{
"id": 1,
"Name": "Susie",
"ownership" : {
"ownershipContextCode" : "C1"
},
"clientIds": [
{
"clientClusterCode": "clientClusterCode_1",
"clientId": "11"
}
]
},
{
"id": 2,
"Name": "John",
"ownership" : {
"ownershipContextCode" : "C2"
},
"clientIds": [
{
"clientClusterCode": "clientClusterCode_2",
"clientId": "22"
}
]
}
]
I am attempting to set a field (ownershipClientCode) as the first element of the clientIds array.
The result should be like that:
[
{
"id": 1,
"Name": "Susie",
"ownership" : {
"ownershipContextCode" : "C1",
"ownershipClientCode" : "clientClusterCode_1"
},
"clientIds": [
{
"clientClusterCode": "clientClusterCode_1",
"clientId": "11"
}
],
},
{
"id": 2,
"Name": "John",
"ownership" : {
"ownershipContextCode" : "C2",
"ownershipClientCode" : "clientClusterCode_2"
},
"clientIds": [
{
"clientClusterCode": "clientClusterCode_2",
"clientId": "22"
}
],
}
]
I'm using this query but I can't get sub object from the first element in the array
db.collection.aggregate([
{
$addFields: {
"Last Semester": {
"$arrayElemAt": [
"$clientIds",
0
]
}
}
}
])
This query add the all object but I want only the field (clientClusterCode).
Some thing like that
db.collection.aggregate([
{
$addFields: {
"Last Semester": {
"$arrayElemAt": [
"$clientIds",
0
].clientClusterCode
}
}
}
])
I'm using mongodb 4.0.0
You're very close: https://mongoplayground.net/p/HY1Pj0P4z12
db.collection.aggregate([
{
$addFields: {
"ownership.ownershipClientCode": {
"$arrayElemAt": [
"$clientIds.clientClusterCode",
0
]
}
}
}
])
You can use the dot notation within the $arrayElemAt as well as when you defining the field name.
To directly set the field, do something like this (use aggregation in the update): https://mongoplayground.net/p/js-usEJSH_A
db.collection.update({},
[
{
$set: {
"ownership.ownershipClientCode": {
"$arrayElemAt": [
"$clientIds.clientClusterCode",
0
]
}
}
}
],
{
multi: true
})
Note: The second method to update needs to be an array, so that it functions as an pipeline.
I have a deeply nested document of family members
[{
"id": 1,
"children" : [
{
"id" : 1,
"grandChildren": [
{
"id" : 1,
"toys": [
{
"id":1
}
]
}
]
},
{
"id" : 2,
"grandChildren": [
{
"id" : 1,
"toys": [
{
"id":1
}
]
}
]
}
]
}]
I'm told the toys are unique to the grandchildren, which are also unique, etc, but there's a chance they're not and I'd like to make absolutely sure when I remove them I'm only removing them for the specific grandchild of the specific child etc,
I have a query that can pull all toys matching the id I was wondering how I can be more specific and burrow down through the specific parents?
db.family.updateOne(
{"id": "1"},
{"$pull" :
{ "children.$[].grandChildren.$[].toys" :
{"id" : "1"}
}
})
All help appreciated
What you want to do is use arrayFilters like so:
db.collection.updateOne({
"id": "1"
},
{
"$pull": {
"children.$[child].grandChildren.$[grandChild].toys": {
"id": "1"
}
}
},
{
arrayFilters: [
{
"child.id": "1"
},
{
"grandChild.id": "1"
}
]
})
Mongo Playground
This question already has answers here:
How to return just the nested documents of an array from all documents
(2 answers)
Closed 3 years ago.
I'm trying to deep query and retrieve specific fields from MongoDB, but unfortunately couldn't able to figure out the correct solution.
Document data:
[ {
"_id": 39127198,
"name": "Mike",
"details": {
"age": 25,
"vehicles":[
{"brand":"Chevrolet","model":"Silverado","plate":"AB11"},
{"brand":"Jeep","model":"Cherokee","plate":"CG678"}
]
}
}, {
"_id": 39127198,
"name": "Taylor",
"details": {
"age": 25,
"vehicles": [
{"brand":"GMC","model":"Sierra","plate":"748397"}
]
}
} ]
My requirement: Return "vehicles" array alone for a specific player. Let's say for user "Mike" in this case.
Here is what I tried;
collection.find( {"name":"Mike"} )
.project( {"details.vehicles" : 1, "_id": 0, "name": 0} )
.toArray(function(err, result) { ... } )
collection.aggregate([
{ $match: { "name":"Mike" } },
{ $project: {"details.vehicles" : 1, "_id": 0, "name": 0} }
]).toArray(function(err, result) { ... } )
Here is what I get for the above code:
[
{
"details": {
"vehicles": [
{"brand":"Chevrolet","model":"Silverado","plate":"AB11"},
{"brand":"Jeep","model":"Cherokee","plate":"CG678"}
]
}
}
]
Expected:
[
{"brand":"Chevrolet","model":"Silverado","plate":"AB11"},
{"brand":"Jeep","model":"Cherokee","plate":"CG678"}
]
I am using MongoClient. MongoDB shell version v4.2.1
You can use $unwind and $replaceRoot stages to achieve this :
db.collection.aggregate([
{
$match: {
"name": "Mike"
}
},
{
$unwind: "$details.vehicles"
},
{
$replaceRoot: {
newRoot: "$details.vehicles"
}
}
])
Will output exactly what you need.
Hope it helps
The query:
db.vehi.aggregate( [
{ $match: { "name":"Mike" } },
{ $project: { "vehicles": "$details.vehicles", "_id": 0 } }
] ).next().vehicles
The exact output:
[
{
"brand" : "Chevrolet",
"model" : "Silverado",
"plate" : "AB11"
},
{
"brand" : "Jeep",
"model" : "Cherokee",
"plate" : "CG678"
}
]
- OR -
This also gets the same result:
db.vehi.find(
{ "name" : "Mike" },
{ "details.vehicles" : 1, _id : 0 }
).next().details.vehicles
How to update a document and insert key-value in subdocument for specific rules?
MongoDB version: 3.4
Use this CLI to insert simulation data
db.country.insertMany([{"_id":"us","groups":[{"group":"1"},{"group":"2"} ]},{"_id":"eu","groups":[{"group":"1"},{"group":"2"}]}, {"_id":"jp","groups":[{"group":"2"}]}])
original data
db.country.find()
{
"_id": "us", "groups": [ { "group" : "1" }, { "group": "2" } ]
}
{
"_id": "eu", "groups": [ { "group" : "1" }, { "group" : "2" } ]
}
{
"_id": "jp", "groups": [ { "group" : "2" } ]
}
How to get this result? ( just add status: happy to group 1 )
{
"_id": "us", "groups": [ { "group" : "1", "status": "happy" }, { "group": "2" } ]
}
{
"_id": "eu", "groups": [ { "group" : "1", "status": "happy" }, { "group" : "2" } ]
}
{
"_id": "jp", "groups": [ { "group" : "2" } ]
}
I know how to select all groups that match group=1
db.country.aggregate([
{'$unwind': '$groups'},
{'$match': {'groups.group': '1'}} ,
{'$project': {'group': '$groups.group', _id:0 }}
])
{ "group" : "1" }
{ "group" : "1" }
and also know how to use update + $set like this
// { "_id": 1, "people": {"name": "tony" } }
db.test.update({_id: 1}, { $set: {'people.country': 'taiwan'}})
// { "_id": 1, "people": {"name": "tony" , "country": "taiwan" } }
but how to merge update + $set and aggregate function? Please help me.
pymongo is OK for me.
How to get this result? ( just add status: happy to group 1 )
Use $ to refer the position of the matched sub-document in array.
db.coll.update_many({'groups.group':'1'}, {'$set': {'groups.$.status': 'happy'}})
see more here
I have this Document in mongodb
{
"name": "test2",
"_id": "1502609098801598ffeca615f5d3dd09087c6",
"events": {
"0": {
"delay": "0",
"actionid": "2"
},
"1": {
"delay": "0",
"actionid": "3"
}
}
}
I want to find documents that contain event with specific actionid
i tried something like these but i can't find what i want
db.mycollection.find({ "events.$.actionid":"2" })
db.mycollection.find({ "events.$**.actionid":"2" })
db.mycollection.find({ "events.$": { $elemMatch: { "actionid":"2"} })
attention please: i can't change document structure and mongodb version is 3.0.6
We can take use of the aggregation feature within mongodb and project the object to an array
db.test.aggregate( [ { "$project" : { "events" : { "$objectToArray" : "$events" } } } ] )
after this we can just use the normal array filtering with a $match
db.test.aggregate([
{ "$project":
{ "events": {"$objectToArray": "$events"} } },
{ "$match":
{ "events.v.actionid" : "2" } } ] )
This will output the following:
{
"_id" : "1502609098801598ffeca615f5d3dd09087c6",
"events" : [
{
"k" : "0",
"v" : {
"delay" : "0",
"actionid" : "2"
}
},
{
"k" : "1",
"v" : {
"delay" : "0",
"actionid" : "3"
}
}
]
}
>
So you might want to project the document back to its orignial structure