Query Mongo for multiple key value pair combinations in array field - mongodb

I am trying to query for Mongo documents based on 1 many key value pairs over a large collection of documents.
I am storing the values in an array called descriptors. I cannot figure out to write the query to consistently return results.
Basically I am trying to write the following SQL query in Mongo
select * from descriptors where
(id=123 and value="Latest based on new infor")
or
(id=3221 and value="Latest new info")
I have tried the following:
db.collection.find({$or: [
{ descriptors:
{
'$elemMatch':
{
id: 123,
value: 'Latest based on new infor',
}
}
},
{ descriptors:
{
'$elemMatch':
{
id: 3221,
value: 'Latest new info',
}
}
}
]
}
Here are sample documents.
{
"_id" : ObjectId("569d62673b020a47f0401325"),
"descriptors" : [
{
"id" : 123,
"name" : "Version",
"value" : "Latest based on new infor",
"parent" : null
},
{
"id" : 345,
"name" : "Eligibility Criteria",
"value" : "Really qualified ",
"parent" : null
}
],
}
{
"_id" : ObjectId("569dac2e4e6247c01bbac47f"),
"descriptors" : [
{
"id" : 3221,
"name" : "Version",
"value" : "Latest new info",
"parent" : null
},
{
"id" : 345,
"name" : "Eligibility Criteria",
"value" : "Different Value",
"parent" : null
}
],
}
{
"_id" : ObjectId("56bce4df7aae8369d8fc705d"),
"descriptors" : [
{
"id" : 3221,
"name" : "Version",
"value" : "Latest based on new infor",
"parent" : null
},
{
"id" : 345.0,
"name" : "Eligibility Criteria",
"value" : "Really qualified",
"parent" : null
}
],
}
Any help would be appreciated,
gsvi

Related

How to upsert nested array object mongodb

I have a document which looks like this
{
_id:'asasasasa23sdsdsd',
source:'page',
url:[]
}
I need to upsert some values/objects to the url array. the objects that need to be upserted looks like this.
{
"type" : "blog",
"value" : "hello blog",
"id" : "1815f620-b45c-4230-85bb-7ba90ac330ed",
"datetime" : "2019-12-26 15:58:33"
}
Then it would look like this
{
_id:'asasasasa23sdsdsd',
source:'page',
url:[{
"type" : "admin",
"value" : "hello admin",
"id" : "1815f620-b45c-4230-85bb-7ba90ac330ed",
"datetime" : "2019-12-26 15:58:33"
},
{
"type" : "blog",
"value" : "hello blog",
"id" : "1815f620-b45c-4230-85bb-7ba90ac330ed",
"datetime" : "2019-12-26 15:58:33"
}
]
}
Here the id and the type fields are unique. I need to insert them if they do not exist or update them if they do.
This is the code that I have tried
db.collection(TABLE_NAME).update(
{ source: data.source },
{
source: data.source,
url: [data.urls]
},
{ upsert: true }
);
With this, it just replaces the array object with a new object. How to upsert instead of replacing the object?
I think this code will help.
let arr = [
{
"type" : "admin",
"value" : "hello admin",
"id" : "1815f620-b45c-4230-85bb-7ba90ac330ed",
"datetime" : "2019-12-26 15:58:33"
},
{
"type" : "blog",
"value" : "hello blog",
"id" : "1815f620-b45c-4230-85bb-7ba90ac330ed",
"datetime" : "2019-12-26 15:58:33"
}
];
db.users.update(
{ _id: doc._id },
{
$set: {
"url": arr
}
}
);

Need find query for dynamic multiple nested collections in mongodb

I need to find collections based nested on values.But my collection having dynamic values . See below code. In which image name keys are dynamic ( _DSC9691.jpg , _DSC9514.JPG ) and " key1 " is dynamic items. Now I need to find collection based on component, material, Subtype
{
"_id" : ObjectId("5ce2df8498f10b276cb466c4"),
"num" : "1",
"lat" : "39.941436099965",
"lon" : "-86.0691700063581",
"images" : {
"_DSC9691.jpg" : {
"key1" : {
"component" : "Sleeve",
"condition" : "",
"sub_type" : {
"Auto Sleeve" : true
},
"material" : "",
"misc" : ""
}
}
}}
{
"_id" : ObjectId("5ce2df8498f10b276cb466c7"),
"num" : "4",
"lat" : "39.9413828961847",
"lon" : "-86.0715084495015",
"images" : {
"_DSC9554.JPG" : {
},
"_DSC9514.JPG" : {
},
"_DSC9622.JPG" : {
}
}}
#Nagendran you won't be able to perform those operations because the nested document that you want to watch isn't named properly. I suggest you to rename that field using a common name and try to use the code bellow. Also remember to not use blank spaces on field names like "Auto Sleeve".
Object:
{
"_id" : ObjectId("5ce2df8498f10b276cb466c7"),
"num" : "4",
"lat" : "39.9413828961847",
"lon" : "-86.0715084495015",
"images" : [
{
"name" : "some name",
"key":
{
"component" : "Sleeve",
"condition" : "",
"sub_type" : {
"Auto_Sleeve" : true
},
"material" : "",
"misc" : ""
},
},
{
"name" : "some name 2",
"key":
{
"component" : "Sleeve 2",
"condition" : "",
"sub_type" : {
"Auto_Sleeve" : true
},
"material" : "",
"misc" : ""
},
},
]
}
Query:
db.collection.find({
"images.key.sub_type.Auto_Sleeve": true
})
If you want you can use aggregation framework to filter inside the "images" nested document.
To get a litle bit more information you can access:
https://docs.mongodb.com/manual/aggregation/
https://docs.mongodb.com/manual/tutorial/query-documents/
https://www.mongodb.com/blog/post/6-rules-of-thumb-for-mongodb-schema-design-part-1
https://university.mongodb.com/

Mongo search within array of tuple objects

I'm using meteor(mongodb) as a backend and I'm trying to query a collection that holds the data this way:
{
"name" : "Some name",
"data" : [
{
"0" : { "type" : "textInput", "value" : "Text", },
"1" : { "type" : "textInput", "value" : "Text", },
"2" : { "type" : "userInput", "value" : {
"userIds" : [ ... "Some mongo objectIds" ... ],
},
},
"3" : { "type" : "textInput", "value" : "Some text", }
},
{
"0" : { "type" : "textInput", "value" : "some text", },
"1" : { "type" : "textInput", "value" : "some text", },
}
],
}
data field can hold any number of objects, each object is a map from number to object with type and value fields.
Specifically, I would like to find all the documents that has a userInput and hold a specific userId (mongo objectId). How can I do it with this data structure?
In this example I can look for "Some mongo objectIds" to find this document (first object of data, index 2).

How to get exact document result from key value type of embedded documents

Let say I have this kind of document structured, the attributes field will be the embedded document
and I've already indexed the attributes.key and attributes.value
1-------------------------------------------------------------------------------------
{
"_id" : ObjectId( "5191d8e5d00560402e000001" ),
"attributes" : [
{ "key" : "pobox","value" : "QaKUWo" },
{ "key" : "city", "value" : "CBDRip" },
{ "key" : "address","value" : "zmycAa" } ],
"email" : "FWAUdl_2#email.com",
"firstname" : "FWAUdl_2"
}
2-------------------------------------------------------------------------------------
{
"_id" : ObjectId( "5191d8e7d00560402e000055" ),
"attributes" : [
{ "key" : "pobox", "value" : "sNFriy" },
{ "key" : "city", "value" : "JPdVrI" },
{ "key" : "address", "value" : "phOluW" } ],
"email" : "hqYNWH_86#email.com",
"firstname" : "hqYNWH_86"
}
My problem is how to get exact document when querying based only on the attributes field,
db.app.find({ attributes.key:address , attributes.value:/.*uw.*/i })
The query result is not as I expected, it should result only the 2nd document only without the 1st document.
I know that I put regex on the attributes.value, I was expecting that it only check for attributes.key that have address value.
And what if I want to filter another key, such like,
db.app.find({ attributes.key:address , attributes.value:/.*uw.*/i , attributes.key:city , attributes.value:/.*ri.*/i })
Any opinion will be helpful guys.
Thx.
I guess you need $elemMatch ( http://docs.mongodb.org/manual/reference/operator/elemMatch/ )
db.test123.find({ attributes : { $elemMatch : { 'key':"address" , 'value':/.*uw.*/i } } }).pretty()
{
"_id" : ObjectId("5191d8e7d00560402e000055"),
"attributes" : [
{
"key" : "pobox",
"value" : "sNFriy"
},
{
"key" : "city",
"value" : "JPdVrI"
},
{
"key" : "address",
"value" : "phOluW"
}
],
"email" : "hqYNWH_86#email.com",
"firstname" : "hqYNWH_86"
}
Just investigated a little and figured out following. The following uses the index mentioned below. You can do a explain() on the find() to check more index usage details
db.testing.getIndexKeys()
[ { "_id" : 1 }, { "attributes.key" : 1, "attributes.value" : 1 } ]
test:Mongo > db.testing.find({$and : [ { attributes : {$elemMatch : {key : 'address', value : /.*uw.*/i }} }, { attributes : {$elemMatch : {key : 'city', value : /.*ri.*/i }} }] }).pretty()
{
"_id" : ObjectId("5191d8e7d00560402e000055"),
"attributes" : [
{
"key" : "pobox",
"value" : "sNFriy"
},
{
"key" : "city",
"value" : "JPdVrI"
},
{
"key" : "address",
"value" : "phOluW"
}
],
"email" : "hqYNWH_86#email.com",
"firstname" : "hqYNWH_86"
}

Deleting a single object from an array of objects in MongoDB

Say we have the following collection of documents:
{ "_id" : ObjectId("50a69fa904c8310609600be3"), "id" : 100, "city" : "San Francisco", "friends" : [ { "id" : 1, "name" : "John" }, { "id" : 2, "name" : "Betty" }, { "id" : 3, "name" : "Harry" } ] }
{ "_id" : ObjectId("50a69fc104c8310609600be4"), "id" : 200, "city" : "Palo Alto", "friends" : [ { "id" : 1, "name" : "Carol" }, { "id" : 2, "name" : "Frank" }, { "id" : 3, "name" : "Norman" } ] }
{ "_id" : ObjectId("50a69fc304c8310609600be5"), "id" : 300, "city" : "Los Angeles", "friends" : [ { "id" : 1, "name" : "Fred" }, { "id" : 2, "name" : "Neal" }, { "id" : 3, "name" : "David" } ] }
.
.
.
Now let's say that Frank (Palo Alto, id=2) is no longer my friend, and I want to delete him from the collection. I thought the following might work, but it doesn't:
db.test.update({"city":"Palo Alto"},{"$pull":{"friends.name":"Frank"}})
I'd like to be able to do something like that. Delete an object within an array within a collection of documents. How do you do this?
You were close. The query should be like this:
db.test.update({"city":"Palo Alto"},{"$pull":{"friends":{"name":"Frank"}}});
$pull takes an object whose field specifies the field array "friends". The value {"name":"Frank"} represents the query (to run inside the array) to find the element to pull out.