Suppose i have following document in some collection
{
"name": "Man1",
"Childrens": [
{
"name": "Children 1",
"age": "12"
},
{
"name": "Children 2",
"age": "18"
},
]
}
how to get output of the query as i.e.get child where age of the child is 18
{
"name": "Children 2",
"age": "18"
}
You need to use $elemMatch to find the document and $elemMatch for projection of the data
db.collection.find({
Childrens: {
$elemMatch: {
age: "18"
}
}
},
{
Childrens: {
$elemMatch: {
age: "18"
}
},
_id: 0
})
OutPut --> here
[
{
"Childrens": [
{
"age": "18",
"name": "Children 2"
}
]
}
]
Related
I want to update the Status field inside array list of Slots where id = "".
Sample data
{
"_id": ObjectId("621e816e7a938400016c5c64"),
"Resource": "abc#gmail.com",
"School": {
"Class": [
{
"Type": "ABC",
"Slots": [
{
"id": "",
"Duration": "1 week",
"Status": "Released",
"Selected": true
},
{
"id": "123",
"Duration": "1 week",
"Status": "Released",
"Selected": true
}
]
}
]
}
}
This is how I am approaching:
db.getCollection("XYZ").update({
"Resource": "abc#gmail.com",
"School.Class": {
"$elemMatch": {
"Type": "ABC",
"Slots.Status": "Released",
"Slots.id": "",
"Slots.Duration": "1 week"
}
}
},
{
$set: {
"School.Class.$[outer].Slots.$[inner].Status": "Confirmed"
}
},
{
"arrayFilters": [
{
"outer.Type": "ABC"
},
{
"inner.Duration": "1 week"
}
]
})
But it is updating the status as confirmed for the both the array list.How can I update the particular field where "Slots.id" : "" . Please forgive me in case of any misalignment or brackets missing in data
If I've understood correctly you are almost there, since you want to update only values where id is "" you have to add that condition into arrayFilters: "inner.id": "".
db.collection.update({
"Resource": "abc#gmail.com",
"School.Class": {
"$elemMatch": {
"Type": "ABC",
"Slots.Status": "Released",
"Slots.id": "",
"Slots.Duration": "1 week"
}
}
},
{
$set: {
"School.Class.$[outer].Slots.$[inner].Status": "Confirmed"
}
},
{
"arrayFilters": [
{
"outer.Type": "ABC"
},
{
"inner.Duration": "1 week",
"inner.id": "" // <--- This line
}
]
})
Example here
Trying to update the nested object for the document in MongoDB.
{
"items" : [
{
"id": 1,
"name": "a",
"child": [
{ "id": 11, "name": "aa" },
{ "id": 12, "name": "bb" },
]
},
]
}
Need to update the child id to 13 whose name is "aa".
O/P, which I am trying to get
{
"items" : [
{
"id": 1,
"name": "a",
"child": [
{ "id": 13, "name": "aa" },
{ "id": 12, "name": "bb" },
]
},
]
}
Work with $[<identifier>] filtered positional operator and arrayFilters.
db.collection.update({
"items.child.name": "aa"
},
{
$set: {
"items.$[].child.$[c].id": 13
}
},
{
arrayFilters: [
{
"c.name": "aa"
}
]
})
Sample Mongo Playground
Let's say I have a collection of objects:
{
"_id": "096439dc-6b57d5-470e-55bb-04ee6378edsg",
"SomeEnt": [
{
"_id": "ce4by887-e589-4b71-e6s4-24d0c586k863",
"userId": "some name",
"name": {
"de": "some name",
"en": "some name",
"fr": "some name",
"es": "some name"
}
},
{
"userId": "some name 2",
"name": {
"en": "some name 2",
"de": "some name 2",
"fr": "some name 2"
}
}
],
"type": {
"_id": "b4951229-6m95-4ui8-ba27-8dcc69lk5217",
"description": {
"en": "something"
},
"code": "something"
},
"Codes": {
"_id": "92ea1201-827b-411a-854b-7832995lkoib",
"type": {
"_id": "1189bd7785-a23f-49f1-be5a-d9l17hy563cd",
"code": "something",
"description": {
"def": "something",
"en": "something"
}
},
"code": "Some Bookings",
}
}
I want a single document where the name inside SomeEnt will be a string with given locale("en" or "fr")
{
"_id": "096439dc-6b57d5-470e-55bb-04ee6378edsg",
"SomeEnt": [
{
"_id": "ce4by887-e589-4b71-e6s4-24d0c586k863",
"userId": "some name",
"name": "some name",
},
{
"userId": "some name 2",
"name": "some name 2",
}
],
"type": {
"_id": "b4951229-6m95-4ui8-ba27-8dcc69lk5217",
"description": {
"en": "something"
},
"code": "something"
},
"Codes": {
"_id": "92ea1201-827b-411a-854b-7832995lkoib",
"type": {
"_id": "1189bd7785-a23f-49f1-be5a-d9l17hy563cd",
"code": "something",
"description": {
"def": "something",
"en": "something"
}
},
"code": "Some Bookings",
}
}
I tried to unwind and then replace the name with the locale but now I'm not understanding how to merge the unwinded documents into 1
[{
$match: {
_id: '096439dc-6b57d5-470e-55bb-04ee6378edsg'
}
}, {
$unwind: {
path: "$SomeEnt"
}
}, {
$project: {
_id: 1,
type: 1,
description: 1,
SomeEnt: {
_id:1,
userId:1,
name: "$SomeEnt.name.en"
},
Codes: {
_id: 1,
code: 1
}
}
}]
How to merge the 2 documents the unwind produced into 1
How to merge the 2 documents the unwind produced into 1
You can use $group stage after $project stage to reconstruct SomeEnt array, and required fields,
{
$group: {
_id: "$_id",
SomeEnt: { $push: "$SomeEnt" },
type: { $first: "$type" },
description: { $first: "$description" },
Codes: { $first: "$Codes" }
}
}
Playground
Second Approach: if you don't use $unwind
$map to iterate loop of SomeEnt array and return required fields
[
{ $match: { _id: "096439dc-6b57d5-470e-55bb-04ee6378edsg" } },
{
$project: {
type: 1,
description: 1,
Codes: {
_id: 1,
code: 1
},
SomeEnt: {
$map: {
input: "$SomeEnt",
in: {
_id: "$$this._id",
userId: "$$this.userId",
name: "$$this.name.en"
}
}
}
}
}
]
Playground
I have the following mongodb documents:
{
"_id": "",
"name": "example1",
"colors": [
{
"id": 1000000,
"properties": [
{
"id": "1000",
"name": "",
"value": "green"
},
{
"id": "2000",
"name": "",
"value": "circle"
}
]
} ]
}
{
"_id": "",
"name": "example2",
"colors": [
{
"id": 1000000,
"properties": [
{
"id": "1000",
"name": "",
"value": "red"
},
{
"id": "4000",
"name": "",
"value": "box"
}
]
} ]
}
I would like to get distinct queries on the value field in the array where id=1000
db.getCollection('product').distinct('colors.properties.value', {'colors.properties.id':{'$eq': 1000}})
but it returns all values in the array.
The expected Result would be:
["green", "red"]
There are a lot of way to do.
$match eliminates unwanted data
$unwind de-structure the array
$addToSet in $group gives the distinct data
The mongo script :
db.collection.aggregate([
{
$match: {
"colors.properties.id": "1000"
}
},
{
"$unwind": "$colors"
},
{
"$unwind": "$colors.properties"
},
{
$match: {
"colors.properties.id": "1000"
}
},
{
$group: {
_id: null,
distinctData: {
$addToSet: "$colors.properties.value"
}
}
}
])
Working Mongo playground
I have Json which have values like state_city details this contains information like which city belongs to which state -
Need to query it for particular state name which will gives me all cities that belongs to that state.
db.collection.find({
"count": 10,
"state.name": "MP"
})
[
{
"collection": "collection1",
"count": 10,
"state": [
{
"name": "MH",
"city": "Mumbai"
},
{
"name": "MH",
"city": "Pune"
},
{
"name": "UP",
"city": "Kanpur"
},
{
"name": "CG",
"city": "Raipur"
}
]
},
{
"collection": "collection2",
"count": 20,
"state": [
{
"name": "MP",
"city": "Indore"
},
{
"name": "MH",
"city": "Bhopal"
},
{
"name": "UP",
"city": "Kanpur"
},
{
"name": "CG",
"city": "Raipur"
}
]
}
]
You have to use aggregate query to get only matching elements in array :
db.collection.aggregate([{
$unwind: "$content.state"
},
{
$match: {
"content.state.name": "MH",
"count": 10
}
},
{
$group: {
_id: "$content.state.city",
}
},
{
$addFields: {
key: 1
}
},
{
$group: {
_id: "$key",
cities: {
$push: "$_id"
}
}
},
{
$project: {
_id: 0,
cities: 1
}
}
])
This query will return :
{
"cities": [
"Pune",
"Mumbai"
]
}
The following query would be the solution.
db.collection.find({ "count": 10, "state":{"name": "MP"}})
For more complex queries, $elemMatch is also available.