MongoDB query for documents with nested objects and array - mongodb

I am having trouble with mongodb querying my object document.
I have the following document:
{
"_id" : ObjectId("1"),
"name" : "Bob",
"fields" : {
"DATE" : [
{
"fromDate" : null,
"values" : [
"2022-08-01"
]
}
]
},
{
"_id" : ObjectId("2"),
"name" : "John",
"fields" : {
"DATE" : [
{
"fromDate" : null,
"values" : [
"1901-08-01"
]
}
]
}
I am trying to get the document where fields.date[0].values is equal to 2022-08-01.
How can I achieve that? Thank you.

You are looking for a nested element value which having some specific value/date.
Since your document is incomplete so, I am creating one for illustrating the solution.
db.employees.insertMany([{
"name" : "Bob",
"fields" : {
"DATE" : [
{
"fromDate" : null,
"values" : [
"2022-08-01"
]
}
]
}},
{
"name" : "John",
"fields" : {
"DATE" : [
{
"fromDate" : null,
"values" : [
"1901-08-01"
]
}
]
}
},
{
"name" : "Eve",
"fields" : {
"DATE" : [
{
"fromDate" : null,
"values" : [
"2022-08-01"
]
}
]
}},
]);
Now we can find the specific value (2022-08-01 as per your requirement) from the nested array/element inside the document. Since the value resides inside "DATE" which is inside the "fields". So we can get that value easily by calling "fields.DATE".
For example you can write some code like this :
db.employees.find({"fields.DATE":{"$elemMatch": {"values": "2022-08-01"}}})
From the above code you will get a result like this.
{ "_id" : ObjectId("62e94392389644cb3fc9c81f"), "name" : "Bob", "fields" : { "DATE" : [ { "fromDate" : null, "values" : [ "2022-08-01" ] } ] } }
{ "_id" : ObjectId("62e94392389644cb3fc9c821"), "name" : "Eve", "fields" : { "DATE" : [ { "fromDate" : null, "values" : [ "2022-08-01" ] } ] } }
Hope this will help you to solve this issue. Happy coding:)

Related

Sort query for dynamic array in Mongo DB

I have a collection in MongoDB like below format. Now i want to know how to apply sorting. Please find example of collection below,
{
"_id" : ObjectId("5e5e140f113a6c3970eef3bb"),
"FormId" : "5cd3a0a0cb20953208fcb549",
"FieldsDatas" : [
{
"FieldId" : "4fbcef5b-d60a-4908-a037-5ff085b70709",
"Value" : [
"202003031"
]
},
{
"FieldId" : "708e1baf-fcd0-45fa-b1de-27f34391c35c",
"Value" : [
"202003031"
]
},
{
"FieldId" : "0b563a80-2b0a-4803-ad7f-652a381e134c",
"Value" : [
"New Source",
"Endpoint"
]
},
{
"FieldId" : "15355b82-4fae-4c09-acb4-13f95e8c2d4e",
"Value" : [
"2020-03-03 13:51:17"
]
},
{
"FieldId" : "1e32a283-34a9-4a7b-b851-3e5ac7f93d2c",
"Value" : [
"tets"
]
}
]
}
{
"_id" : ObjectId("5e5e1c89113a6c3970eef3bc"),
"FormId" : "5cd3a0a0cb20953208fcb549"
"FieldsDatas" : [
{
"FieldId" : "708e1baf-fcd0-45fa-b1de-27f34391c35c",
"Value" : [
"202003032"
]
},
{
"FieldId" : "0eca0881-a69b-4db3-b8b1-d74b0a16d4ef",
"Value" : [
"20200303_2#mail.com"
]
},
{
"FieldId" : "2da67714-aaf3-433d-9a86-1b48c75470ec",
"Value" : [
"mani lj"
]
},
{
"FieldId" : "a0b26aac-cad0-4c5e-83b4-9a01ac4ce97a",
"Value" : []
},
{
"FieldId" : "15355b82-4fae-4c09-acb4-13f95e8c2d4e",
"Value" : [
"2020-03-03 14:29:23"
]
}
]
}
For above collection i have date inside the array of objects called FieldsDatas where "FieldId": "15355b82-4fae-4c09-acb4-13f95e8c2d4e" in that same "Value" array has datetime. I want to sort the result based in this datetime.
I have a filter query. How to add sort query for above scenario?
db.getCollection('Collection').find({
"$and":[
{
FieldsDatas: {
$elemMatch:{
FieldId:'955c9843-1535-4df8-a1c4-09430ac9f6ba',
Value: { $ne: ["Contact"] }
}
}
}
]
})
.limit(5)
.skip(30);
Anyone please help me to add sorting for this query like above datetime field.
Any possibilities to achieve this by Stored procedure or functions. Please let me know.
Thanks in advance,
Mani

Update double nested array mongodb

I have the below document which contains double nested array format. I have to update the "level" field to "Senior Engineer" when the "someKey":"somevalue" and "Company":"Company1" and "Name":"Nandhi".
Document
{
"_id" : "777",
"someKey" : "someValue",
"someArray" : [
{
"Company" : "Company1",
"someNestedArray" : [
{
"name" : "Nandhi",
"level" : "Junior Engineer"
},
{
"name" : "Rajan",
"level" : "Senio Engineer"
}
]
}],
{
"Company" : "Company2",
"someNestedArray" : [
{
"name" : "Nandhi",
"level" : "Junior Engineer"
},
{
"name" : "Rajan",
"level" : "Senio Engineer"
}
]
}
]
}
Update Query I tried
db.Test123.updateOne(
{"someKey" : "someValue","someArray.Company":"Company1"},
{$set:{"someArray.$[someNestedArray].level":"Senior Developer"}},
{arrayFilters:[{"someNestedArray.name":"Nandhi"}]}
);
Output Screenshot
As you can seen that, the modifiedCount returns 0. Please advice on this!
You need to define arrayFilter for every level of nesting, try:
db.Test123.update(
{ "someKey" : "someValue" },
{ "$set": { "someArray.$[someArrayDoc].someNestedArray.$[someNestedArrayDoc].level": "Senior Developer" } },
{ arrayFilters: [ {"someArrayDoc.Company": "Company1"}, { "someNestedArrayDoc.name": "Nandhi" } ] }
)

Retrieving group by result with arrays in mongo

I have mongo documents in the following format. I want to get the devices_ids for each unique phone_numbers but my mongo query is not giving proper result.
Can anyone point out my problem ?
{
"_id" : ObjectId("56cf21562e7b232d022f334e871"),
"uid" : 5,
"device_id" : "352136234234325",
"name" : "user1",
"email" : ["user1#mail.com" ],
"phone_number" : [
"+919890273451"
]
}
{
"_id" : ObjectId("56cf21562e7b2d032422f334e872"),
"uid" : 15,
"device_id" : "3521360123444",
"name" : "user1",
"email" : [ "user1#mail.com"],
"phone_number" : [
"+919890273451"
]
}
{
"_id" : ObjectId("56cf21562342e7b2d022f334e873"),
"uid" : 51,
"device_id" : "352136067208559",
"name" : "user1",
"email" : [ "user1#mail.com"],
"phone_number" : [
"+919890273451"
]
}
My expected output is
{
"phone_number" : "+919890273451",
device_ids : ["352136067208559","3521360123444","352136234234325"]}
}
I have tried this query:
db.contact.aggregate([{
$unwind: "$phone_number"
},
{$group: {"_id":"$phone_number"},
device_ids: { $push: { user: "$device_id"} }
}
], {
allowDiskUse:true,
cursor:{}
});
when using $push you don't need to specify touple name - just push plain value.
Please see below:
db.coll.aggregate([{
$unwind : "$phone_number"
}, {
$group : {
_id : "$phone_number",
device_ids : {
$addToSet : "$device_id"
}
}
}
])

Get results in nested objects

This is my collection structure and I want to filter all the results for a defined reference:
{
"_id" : "5xFusfnvRobfMhRKE",
"book" : "Lorem",
"publisher" : "Lorem",
"author" : "Lorem",
"edition" : [
{
"edition" : "Lorem",
"year" : 2015,
"section" : [
{
"pageNumbers" : "12",
"reference" : "4NoHjACkjHJ8mavv9"
}
]
}
]
}
My attempt was Collection.find({'edition.section.reference': '4NoHjACkjHJ8mavv9'}), but that doesn't work. I would expect this matches the above example.
I think this query can help you-
db.collection.find({"edition.section.reference":"4NoHjACkjHJ8mavv9"},{}).pretty()
You have to use 'db' before the collection_name ie. db.collection.find() and for your problem you actually did it right but just missed out on 'db'.
db.sys_test.insert({"-_id":10,"edition":[{"section":[{"reference":"101"}]}]})
db.sys_test.find({"edition.section.reference":"101"}).pretty()
{
"_id" : ObjectId("55faba519d0ff7079e6f9817"),
"-_id" : 10,
"edition" : [
{
"section" : [
{
"reference" : "101"
}
]
}
]
}

Ask update and delete multiple array in MongoDb

I have a real case in my project:
> db.foo.insert({a:'1',
... province: [{id:'1',name:'Yogyakarta',state:[{id:'1',name:'bantul'}]}]
... })
Then I find()...
> db.foo.find();
> { "_id" : ObjectId("5279ef4c6cfd9d5c0e19bbe0"),
"a" : "1",
"province" : [
{"id" : "1",
"name" : "Yogyakarta",
"state" : [
{"id" : "1","name" : "bantul" }
]
}
]
}
how to remove and update state with id='1'
REMOVE
To remove the documents that match a deletion criteria, call the remove() method with the <query> parameter.
db.foo.remove({'province.state.id': '1'})
Example
First, insert data Yogyakarta - Bantul
db.foo.insert({a:'1', province: [{id:'1',name:'Yogyakarta',state:[{id:'1',name:'bantul'}]}] })
Insert data Jakarta - Jakarta Selatan
db.foo.insert({a:'1', province: [{id:'2',name:'Jakarta',state:[{id:'2',name:'Jakarta Selatan'}]}] })
Now, you have two documents
db.foo.find();
Result
[
{ "a" : "1", "_id" : { "$oid" : "527b54c6cc937439340367f9" }, "province" : [ { "name" : "Yogyakarta", "id" : "1", "state" : [ { "name" : "bantul", "id" : "1" } ] } ] },
{ "a" : "1", "_id" : { "$oid" : "527b54d3cc937439340367fa" }, "province" : [ { "name" : "Jakarta", "id" : "2", "state" : [ { "name" : "Jakarta Selatan", "id" : "2" } ] } ] }
]
Now, delete document where the subdocument province contains a field state whose value 1.
db.foo.remove({'province.state.id': '1'})
Check
db.foo.find();
Now, you have one document
[
{ "a" : "1", "_id" : { "$oid" : "527b54d3cc937439340367fa" }, "province" : [ { "name" : "Jakarta", "id" : "2", "state" : [ { "name" : "Jakarta Selatan", "id" : "2" } ] } ] }
]
UPDATE
By default, the update() method updates a single document. If the multi option is set to true, the method updates all documents that match the query criteria.
db.foo.update({'province.state.id': '2'}, { $set: {'a': '2'} })
Check
db.foo.find();
Result
[
{ "a" : "2", "_id" : { "$oid" : "527b54d3cc937439340367fa" }, "province" : [ { "name" : "Jakarta", "id" : "2", "state" : [ { "name" : "Jakarta Selatan", "id" : "2" } ] } ] }
]