Reputation: 1561
I'm new to mongo and am trying to do a very simple query in this collection:
{
"_id" : ObjectId("gdrgrdgrdgdr"),
"administrators" : {
"-HGFsfes" : {
"name" : "Jose",
"phone" : NumberLong(124324)
},
"-HGFsfqs" : {
"name" : "Peter",
"phone" : "+43242342"
}
},
"countries" : {
"-dgfgrdg : {
"lang" : "en",
"name" : "Canada"
},
"-grdgrdg" : {
"lang" : "en",
"name" : "USA"
}
}
}
How do I make a query that returns the results of administrators with name like "%Jos%" for example.
What I did until now is this: db.getCollection('coll').find({ "administrators.name": /Jos/});
And variations of this. But every thing I tried returns zero results.
What am I doing wrong?
Thanks in advance!
Upvotes: 2
Views: 7937
Reputation: 4353
Ok, think i've found a better solution for you, with aggregation framework. Run the following query on your current collection, will return you all administrators with name "LIKE" jos (case insensitive with i option) :
db.test1.aggregate(
[
{
$project: {
administrators:{ $objectToArray: "$administrators"}
}
},
{
$unwind: {
path : "$administrators"
}
},
{
$replaceRoot: {
newRoot:"$administrators"
}
},
{
$match: {
"v.name":/jos/i
}
},
]
);
Output
{
"k" : "-HGFsfes",
"v" : {
"name" : "Jose",
"phone" : NumberLong(124324)
}
}
"k" and "v" are coming from "$objectToArray" operator, you can add a $project stage to rename them (or discard if k value doesn't matter)
Not sure for Robomongo testing but in Studio 3T, formerly Robomongo, you can either copy/paste this query in Intellishell console, or copy/import in aggregation tab, (small icon 'paste from the clipboard').
Hope it helps.
Upvotes: 1
Reputation: 3033
You need to use query like this:
db.collection_name.find({})
So if your collection name is coll, then it would be:
db.coll.find({"administrators.-HGFsfes.name": /Jos/});
Look this for like query in mongo.
Also, try with regex pattern like this:
db.coll.find({"administrators..-HGFsfes.name": {"$regex":"Jos", "$options":"i"}}});
It will give you only one result because your data is not an array as below in screenshot:
If you want multiple results, then you need to restructure your data.
Upvotes: 1
Reputation: 4353
Your mistake is that administrators is not an array, but an object with fields that are themselves objects with name field. Right query will be
{ "administrators.-HGFsfes.name": /Jos/}
Unfortunatelly this way you're only querying -HGFsfes name field, not other administrator name field.
To achieve what you want, the only thing to do is to replace administrators object by an array, so your document will look like this :
{
"administrators" : [
{
"id" : "-HGFsfes",
"name" : "Jose",
"phone" : 124324
},
{
"id" : "-HGFsfqs",
"name" : "Peter",
"phone" : "+43242342"
}
],
countries : ...
}
This way your query will work.
BUT it will return documents where at least one entry in administrators array has the matching name field. To return only administrator matching element, and not whole document, check this question and my answer for unwind/match/group aggregation pipeline.
Upvotes: 1