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
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
}
}
);
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/
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).
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"
}
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.