Retrieve only the queried element in an object array in MongoDB collectionHow to filter array in subdocument with MongoDBHow to get a specific embedded document inside a MongoDB collection?Get particular element from mongoDB arraymongo .find return specific field only for all userMongodb Aggregation : How to return only matching elements of an arrayMongoDB retrieving selected objects from nested documentsReturning only sub document based on subdocument _id which is the items of array field of the mongodb documentMongo Only Return Elements of Array Matching QueryHow to get a specific object from an array field with mongooseQuery on date range with mongoHow to query MongoDB with “like”?Query for documents where array size is greater than 1why isnt mongo returning object in array?MongoDB return all the fields in a collectionMongoDB: How to find out if an array field contains an element?MongoDB - projection of all array element match a querycompare two collections in mongodb using java or an simple querymongodb query and return specific elements in array of documents, return some result even if nullMongodb comparing object arrays keysRetrieve a specific element in an object array in MongoDB collection
Why didn't Thatcher give Hong Kong to Taiwan?
'Hard work never hurt anyone' Why not 'hurts'?
Different past tense for various *et words
Why do fuses burn at a specific current?
garage light with two hots and one neutral
What are the French equivalents of "blow away the cobwebs"?
How to say "too quickly", "too recklessly" etc
How do we know if a dialogue sounds unnatural without asking for feedback?
Datasets of Large Molecules
Is the mnemonic in Winter's Tale real?
How Powerful a Starship Coilgun Can We Make?
Which is the best password hashing algorithm in .Net Core?
Replace a motion-sensor/timer with simple single pole switch
If the government illegally doesn't ask for article 50 extension, can parliament do it instead?
Order by inside subquery
Some questions about Lightning and Tor
How does Harry wear the invisibility cloak?
How to run a command 1 out of N times in Bash
What laws protect minority share holders from having their share rights changed by special resolution?
Why are my split equations aligned to right by default?
Inserting command output into multiline string
To which country did MiGs in Top Gun belong?
How can I portray a character with no fear of death, without them sounding utterly bored?
Can my UK debt be collected because I have to return to US?
Retrieve only the queried element in an object array in MongoDB collection
How to filter array in subdocument with MongoDBHow to get a specific embedded document inside a MongoDB collection?Get particular element from mongoDB arraymongo .find return specific field only for all userMongodb Aggregation : How to return only matching elements of an arrayMongoDB retrieving selected objects from nested documentsReturning only sub document based on subdocument _id which is the items of array field of the mongodb documentMongo Only Return Elements of Array Matching QueryHow to get a specific object from an array field with mongooseQuery on date range with mongoHow to query MongoDB with “like”?Query for documents where array size is greater than 1why isnt mongo returning object in array?MongoDB return all the fields in a collectionMongoDB: How to find out if an array field contains an element?MongoDB - projection of all array element match a querycompare two collections in mongodb using java or an simple querymongodb query and return specific elements in array of documents, return some result even if nullMongodb comparing object arrays keysRetrieve a specific element in an object array in MongoDB collection
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
Suppose you have the following documents in my collection:
"_id":ObjectId("562e7c594c12942f08fe4192"),
"shapes":[
"shape":"square",
"color":"blue"
,
"shape":"circle",
"color":"red"
]
,
"_id":ObjectId("562e7c594c12942f08fe4193"),
"shapes":[
"shape":"square",
"color":"black"
,
"shape":"circle",
"color":"green"
]
Do query:
db.test.find("shapes.color": "red", "shapes.color": 1)
Or
db.test.find(shapes: "$elemMatch": color: "red", "shapes.color": 1)
Returns matched document (Document 1), but always with ALL array items in shapes:
"shapes":
[
"shape": "square", "color": "blue",
"shape": "circle", "color": "red"
]
However, I'd like to get the document (Document 1) only with the array that contains color=red:
"shapes":
[
"shape": "circle", "color": "red"
]
How can I do this?
mongodb mongodb-query aggregation-framework projection
add a comment |
Suppose you have the following documents in my collection:
"_id":ObjectId("562e7c594c12942f08fe4192"),
"shapes":[
"shape":"square",
"color":"blue"
,
"shape":"circle",
"color":"red"
]
,
"_id":ObjectId("562e7c594c12942f08fe4193"),
"shapes":[
"shape":"square",
"color":"black"
,
"shape":"circle",
"color":"green"
]
Do query:
db.test.find("shapes.color": "red", "shapes.color": 1)
Or
db.test.find(shapes: "$elemMatch": color: "red", "shapes.color": 1)
Returns matched document (Document 1), but always with ALL array items in shapes:
"shapes":
[
"shape": "square", "color": "blue",
"shape": "circle", "color": "red"
]
However, I'd like to get the document (Document 1) only with the array that contains color=red:
"shapes":
[
"shape": "circle", "color": "red"
]
How can I do this?
mongodb mongodb-query aggregation-framework projection
add a comment |
Suppose you have the following documents in my collection:
"_id":ObjectId("562e7c594c12942f08fe4192"),
"shapes":[
"shape":"square",
"color":"blue"
,
"shape":"circle",
"color":"red"
]
,
"_id":ObjectId("562e7c594c12942f08fe4193"),
"shapes":[
"shape":"square",
"color":"black"
,
"shape":"circle",
"color":"green"
]
Do query:
db.test.find("shapes.color": "red", "shapes.color": 1)
Or
db.test.find(shapes: "$elemMatch": color: "red", "shapes.color": 1)
Returns matched document (Document 1), but always with ALL array items in shapes:
"shapes":
[
"shape": "square", "color": "blue",
"shape": "circle", "color": "red"
]
However, I'd like to get the document (Document 1) only with the array that contains color=red:
"shapes":
[
"shape": "circle", "color": "red"
]
How can I do this?
mongodb mongodb-query aggregation-framework projection
Suppose you have the following documents in my collection:
"_id":ObjectId("562e7c594c12942f08fe4192"),
"shapes":[
"shape":"square",
"color":"blue"
,
"shape":"circle",
"color":"red"
]
,
"_id":ObjectId("562e7c594c12942f08fe4193"),
"shapes":[
"shape":"square",
"color":"black"
,
"shape":"circle",
"color":"green"
]
Do query:
db.test.find("shapes.color": "red", "shapes.color": 1)
Or
db.test.find(shapes: "$elemMatch": color: "red", "shapes.color": 1)
Returns matched document (Document 1), but always with ALL array items in shapes:
"shapes":
[
"shape": "square", "color": "blue",
"shape": "circle", "color": "red"
]
However, I'd like to get the document (Document 1) only with the array that contains color=red:
"shapes":
[
"shape": "circle", "color": "red"
]
How can I do this?
mongodb mongodb-query aggregation-framework projection
mongodb mongodb-query aggregation-framework projection
edited Jan 3 at 6:45
nabster
6731 gold badge10 silver badges28 bronze badges
6731 gold badge10 silver badges28 bronze badges
asked Oct 21 '10 at 7:31
SebtmSebtm
2,9378 gold badges24 silver badges31 bronze badges
2,9378 gold badges24 silver badges31 bronze badges
add a comment |
add a comment |
11 Answers
11
active
oldest
votes
MongoDB 2.2's new $elemMatch projection operator provides another way to alter the returned document to contain only the first matched shapes element:
db.test.find(
"shapes.color": "red",
_id: 0, shapes: $elemMatch: color: "red");
Returns:
"shapes" : ["shape": "circle", "color": "red"]
In 2.2 you can also do this using the $ projection operator, where the $ in a projection object field name represents the index of the field's first matching array element from the query. The following returns the same results as above:
db.test.find("shapes.color": "red", _id: 0, 'shapes.$': 1);
MongoDB 3.2 Update
Starting with the 3.2 release, you can use the new $filter aggregation operator to filter an array during projection, which has the benefit of including all matches, instead of just the first one.
db.test.aggregate([
// Get just the docs that contain a shapes element where color is 'red'
$match: 'shapes.color': 'red',
$project:
shapes: $filter:
input: '$shapes',
as: 'shape',
cond: $eq: ['$$shape.color', 'red']
,
_id: 0
])
Results:
[
"shapes" : [
"shape" : "circle",
"color" : "red"
]
]
13
any solution if I want it to return every elements that matches it instead of just the first?
– Steve Ng
Dec 25 '13 at 8:12
@JohnnyHK, yup, i used it eventually, thanks!
– Steve Ng
Dec 26 '13 at 6:19
I'm afraid I am using Mongo 3.0.X :-(
– charliebrownie
Jan 10 '16 at 20:33
@charliebrownie Then use one of the other answers that useaggregate.
– JohnnyHK
Jan 10 '16 at 21:14
1
This also works:db.test.find(, shapes: $elemMatch: color: "red");
– Paul
Jul 14 '17 at 19:15
|
show 3 more comments
The new Aggregation Framework in MongoDB 2.2+ provides an alternative to Map/Reduce. The $unwind operator can be used to separate your shapes array into a stream of documents that can be matched:
db.test.aggregate(
// Start with a $match pipeline which can take advantage of an index and limit documents processed
$match :
"shapes.color": "red"
,
$unwind : "$shapes" ,
$match :
"shapes.color": "red"
)
Results in:
"result" : [
"_id" : ObjectId("504425059b7c9fa7ec92beec"),
"shapes" :
"shape" : "circle",
"color" : "red"
],
"ok" : 1
6
@JohnnyHK: In this case,$elemMatchis another option. I actually got here by way of a Google Group question where $elemMatch wouldn't work because it only returns the first match per document.
– Stennie
Sep 3 '12 at 4:24
1
Thanks, I wasn't aware of that limitation so that's good to know. Sorry for deleting my comment you're responding to, I decided to post another answer instead and didn't want to confuse people.
– JohnnyHK
Sep 3 '12 at 4:35
3
@JohnnyHK: No worries, there are now three useful answers for the question ;-)
– Stennie
Sep 3 '12 at 4:41
For other searchers, in addition to this I also tried adding$project : shapes : 1- which seemed to work and would be helpful if the enclosing documents were large and you just wanted to view theshapeskey values.
– user1063287
Dec 4 '14 at 8:23
2
@calmbird I updated the example to include an initial $match stage. If you're interested in a more efficient feature suggestion I would watch/upvote SERVER-6612: Support projecting multiple array values in a projection like the $elemMatch projection specifier in the MongoDB issue tracker.
– Stennie
Jan 28 '15 at 8:52
|
show 3 more comments
Caution: This answer provides a solution that was relevant at that time, before the new features of MongoDB 2.2 and up were introduced. See the other answers if you are using a more recent version of MongoDB.
The field selector parameter is limited to complete properties. It cannot be used to select part of an array, only the entire array. I tried using the $ positional operator, but that didn't work.
The easiest way is to just filter the shapes in the client.
If you really need the correct output directly from MongoDB, you can use a map-reduce to filter the shapes.
function map()
filteredShapes = [];
this.shapes.forEach(function (s)
if (s.color === "red")
filteredShapes.push(s);
);
emit(this._id, shapes: filteredShapes );
function reduce(key, values)
return values[0];
res = db.test.mapReduce(map, reduce, query: "shapes.color": "red" )
db[res.result].find()
add a comment |
Another interesing way is to use $redact, which is one of the new aggregation features of MongoDB 2.6. If you are using 2.6, you don't need an $unwind which might cause you performance problems if you have large arrays.
db.test.aggregate([
$match:
shapes: $elemMatch: color: "red"
,
$redact :
$cond:
if: $or : [ $eq: ["$color","red"] , $not : "$color" ],
then: "$$DESCEND",
else: "$$PRUNE"
]);
$redact "restricts the contents of the documents based on information stored in the documents themselves". So it will run only inside of the document. It basically scans your document top to the bottom, and checks if it matches with your if condition which is in $cond, if there is match it will either keep the content($$DESCEND) or remove($$PRUNE).
In the example above, first $match returns the whole shapes array, and $redact strips it down to the expected result.
Note that $not:"$color" is necessary, because it will scan the top document as well, and if $redact does not find a color field on the top level this will return false that might strip the whole document which we don't want.
1
perfect answer. As you mentioned $unwind will consume lot of RAM. So this will be better when compared.
– manojpt
Apr 21 '15 at 11:21
I have a doubt. In the example, "shapes" is an array. Will "$redact" scan all the objects in the "shapes" array ?? How this will be good with respect to performance??
– manojpt
Apr 23 '15 at 8:13
not all of it, but the result of your first match. That is the reason why you put$matchas your first aggregate stage
– anvarik
Apr 23 '15 at 16:36
okkk.. if an index created on "color" field, even then it will scan all the objects in the "shapes" array??? Which could be the efficient way of matching multiple objects in an array???
– manojpt
Apr 24 '15 at 4:47
2
Brilliant! I do not understand how $eq works here. I left it off originally and this didn't work for me. Somehow, it looks in the array of shapes to find the match, but the query never specifies which array to look in. Like, if the documents had shapes and, for example, sizes; would $eq look in both arrays for matches? Is $redact just looking for anything within the document that matches the 'if' condition?
– Onosa
Dec 30 '15 at 14:46
|
show 1 more comment
Better you can query in matching array element using $slice is it helpful to returning the significant object in an array.
db.test.find("shapes.color" : "blue", "shapes.$" : 1)
$slice is helpful when you know the index of the element, but sometimes you want
whichever array element matched your criteria. You can return the matching element
with the $ operator.
add a comment |
db.getCollection('aj').find("shapes.color":"red","shapes.$":1)
OUTPUTS
"shapes" : [
"shape" : "circle",
"color" : "red"
]
add a comment |
The syntax for find in mongodb is
db.<collection name>.find(query, projection);
and the second query that you have written, that is
db.test.find(
shapes: "$elemMatch": color: "red",
"shapes.color":1)
in this you have used the $elemMatch operator in query part, whereas if you use this operator in the projection part then you will get the desired result. You can write down your query as
db.users.find(
"shapes.color":"red",
_id:0, shapes: $elemMatch : color: "red")
This will give you the desired result.
1
This works for me. However, It appears that"shapes.color":"red"in the query parameter (the first parameter of the find method) is not necessary. You can replace it withand get the same results.
– Erik Olson
May 9 '14 at 20:35
2
@ErikOlson Your suggestion is right in the above case, where we need to find all the document that with red color and to apply the projection on them only. But let's say if somebody requires to find out all the document that have color blue but it should return only those element of that shapes array that have color red. In this case the above query can be referenced by somebody else also..
– Vicky
May 11 '14 at 9:22
This seems to be the easiest, but I can't make it work it. It only returns the first matching subdocument.
– newman
Aug 29 '15 at 23:05
add a comment |
Thanks to JohnnyHK.
Here I just want to add some more complex usage.
// Document
"_id" : 1
"shapes" : [
"shape" : "square", "color" : "red",
"shape" : "circle", "color" : "green"
]
"_id" : 2
"shapes" : [
"shape" : "square", "color" : "red",
"shape" : "circle", "color" : "green"
]
// The Query
db.contents.find(
"_id" : ObjectId(1),
"shapes.color":"red"
,
"_id": 0,
"shapes" :
"$elemMatch":
"color" : "red"
)
//And the Result
"shapes":[
"shape" : "square",
"color" : "red"
]
add a comment |
You just need to run query
db.test.find(
"shapes.color": "red",
shapes: $elemMatch: color: "red");
output of this query is
"_id" : ObjectId("562e7c594c12942f08fe4192"),
"shapes" : [
"shape" : "circle", "color" : "red"
]
as you expected it'll gives the exact field from array that matches color:'red'.
add a comment |
along with $project it will be more appropriate other wise matching elements will be clubbed together with other elements in document.
db.test.aggregate(
"$unwind" : "$shapes" ,
"$match" :
"shapes.color": "red"
,
"$project":
"_id":1,
"item":1
)
can you pls describe that this accomplishes with an input and output set?
– Alexander Mills
Nov 24 '15 at 17:13
add a comment |
db.test.find( "shapes.color": "red", _id: 0)
1
Welcome to Stack Overflow! Thank you for the code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by describing why this is a good solution to the problem, and would make it more useful to future readers with other similar questions. Please edit your answer to add some explanation, including the assumptions you've made.
– sepehr
Oct 25 '18 at 15:06
add a comment |
protected by Samuel Liew♦ Oct 5 '15 at 9:21
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
11 Answers
11
active
oldest
votes
11 Answers
11
active
oldest
votes
active
oldest
votes
active
oldest
votes
MongoDB 2.2's new $elemMatch projection operator provides another way to alter the returned document to contain only the first matched shapes element:
db.test.find(
"shapes.color": "red",
_id: 0, shapes: $elemMatch: color: "red");
Returns:
"shapes" : ["shape": "circle", "color": "red"]
In 2.2 you can also do this using the $ projection operator, where the $ in a projection object field name represents the index of the field's first matching array element from the query. The following returns the same results as above:
db.test.find("shapes.color": "red", _id: 0, 'shapes.$': 1);
MongoDB 3.2 Update
Starting with the 3.2 release, you can use the new $filter aggregation operator to filter an array during projection, which has the benefit of including all matches, instead of just the first one.
db.test.aggregate([
// Get just the docs that contain a shapes element where color is 'red'
$match: 'shapes.color': 'red',
$project:
shapes: $filter:
input: '$shapes',
as: 'shape',
cond: $eq: ['$$shape.color', 'red']
,
_id: 0
])
Results:
[
"shapes" : [
"shape" : "circle",
"color" : "red"
]
]
13
any solution if I want it to return every elements that matches it instead of just the first?
– Steve Ng
Dec 25 '13 at 8:12
@JohnnyHK, yup, i used it eventually, thanks!
– Steve Ng
Dec 26 '13 at 6:19
I'm afraid I am using Mongo 3.0.X :-(
– charliebrownie
Jan 10 '16 at 20:33
@charliebrownie Then use one of the other answers that useaggregate.
– JohnnyHK
Jan 10 '16 at 21:14
1
This also works:db.test.find(, shapes: $elemMatch: color: "red");
– Paul
Jul 14 '17 at 19:15
|
show 3 more comments
MongoDB 2.2's new $elemMatch projection operator provides another way to alter the returned document to contain only the first matched shapes element:
db.test.find(
"shapes.color": "red",
_id: 0, shapes: $elemMatch: color: "red");
Returns:
"shapes" : ["shape": "circle", "color": "red"]
In 2.2 you can also do this using the $ projection operator, where the $ in a projection object field name represents the index of the field's first matching array element from the query. The following returns the same results as above:
db.test.find("shapes.color": "red", _id: 0, 'shapes.$': 1);
MongoDB 3.2 Update
Starting with the 3.2 release, you can use the new $filter aggregation operator to filter an array during projection, which has the benefit of including all matches, instead of just the first one.
db.test.aggregate([
// Get just the docs that contain a shapes element where color is 'red'
$match: 'shapes.color': 'red',
$project:
shapes: $filter:
input: '$shapes',
as: 'shape',
cond: $eq: ['$$shape.color', 'red']
,
_id: 0
])
Results:
[
"shapes" : [
"shape" : "circle",
"color" : "red"
]
]
13
any solution if I want it to return every elements that matches it instead of just the first?
– Steve Ng
Dec 25 '13 at 8:12
@JohnnyHK, yup, i used it eventually, thanks!
– Steve Ng
Dec 26 '13 at 6:19
I'm afraid I am using Mongo 3.0.X :-(
– charliebrownie
Jan 10 '16 at 20:33
@charliebrownie Then use one of the other answers that useaggregate.
– JohnnyHK
Jan 10 '16 at 21:14
1
This also works:db.test.find(, shapes: $elemMatch: color: "red");
– Paul
Jul 14 '17 at 19:15
|
show 3 more comments
MongoDB 2.2's new $elemMatch projection operator provides another way to alter the returned document to contain only the first matched shapes element:
db.test.find(
"shapes.color": "red",
_id: 0, shapes: $elemMatch: color: "red");
Returns:
"shapes" : ["shape": "circle", "color": "red"]
In 2.2 you can also do this using the $ projection operator, where the $ in a projection object field name represents the index of the field's first matching array element from the query. The following returns the same results as above:
db.test.find("shapes.color": "red", _id: 0, 'shapes.$': 1);
MongoDB 3.2 Update
Starting with the 3.2 release, you can use the new $filter aggregation operator to filter an array during projection, which has the benefit of including all matches, instead of just the first one.
db.test.aggregate([
// Get just the docs that contain a shapes element where color is 'red'
$match: 'shapes.color': 'red',
$project:
shapes: $filter:
input: '$shapes',
as: 'shape',
cond: $eq: ['$$shape.color', 'red']
,
_id: 0
])
Results:
[
"shapes" : [
"shape" : "circle",
"color" : "red"
]
]
MongoDB 2.2's new $elemMatch projection operator provides another way to alter the returned document to contain only the first matched shapes element:
db.test.find(
"shapes.color": "red",
_id: 0, shapes: $elemMatch: color: "red");
Returns:
"shapes" : ["shape": "circle", "color": "red"]
In 2.2 you can also do this using the $ projection operator, where the $ in a projection object field name represents the index of the field's first matching array element from the query. The following returns the same results as above:
db.test.find("shapes.color": "red", _id: 0, 'shapes.$': 1);
MongoDB 3.2 Update
Starting with the 3.2 release, you can use the new $filter aggregation operator to filter an array during projection, which has the benefit of including all matches, instead of just the first one.
db.test.aggregate([
// Get just the docs that contain a shapes element where color is 'red'
$match: 'shapes.color': 'red',
$project:
shapes: $filter:
input: '$shapes',
as: 'shape',
cond: $eq: ['$$shape.color', 'red']
,
_id: 0
])
Results:
[
"shapes" : [
"shape" : "circle",
"color" : "red"
]
]
edited Sep 25 '18 at 18:04
Faraz Durrani
3,2172 gold badges13 silver badges41 bronze badges
3,2172 gold badges13 silver badges41 bronze badges
answered Sep 3 '12 at 4:19
JohnnyHKJohnnyHK
225k45 gold badges480 silver badges393 bronze badges
225k45 gold badges480 silver badges393 bronze badges
13
any solution if I want it to return every elements that matches it instead of just the first?
– Steve Ng
Dec 25 '13 at 8:12
@JohnnyHK, yup, i used it eventually, thanks!
– Steve Ng
Dec 26 '13 at 6:19
I'm afraid I am using Mongo 3.0.X :-(
– charliebrownie
Jan 10 '16 at 20:33
@charliebrownie Then use one of the other answers that useaggregate.
– JohnnyHK
Jan 10 '16 at 21:14
1
This also works:db.test.find(, shapes: $elemMatch: color: "red");
– Paul
Jul 14 '17 at 19:15
|
show 3 more comments
13
any solution if I want it to return every elements that matches it instead of just the first?
– Steve Ng
Dec 25 '13 at 8:12
@JohnnyHK, yup, i used it eventually, thanks!
– Steve Ng
Dec 26 '13 at 6:19
I'm afraid I am using Mongo 3.0.X :-(
– charliebrownie
Jan 10 '16 at 20:33
@charliebrownie Then use one of the other answers that useaggregate.
– JohnnyHK
Jan 10 '16 at 21:14
1
This also works:db.test.find(, shapes: $elemMatch: color: "red");
– Paul
Jul 14 '17 at 19:15
13
13
any solution if I want it to return every elements that matches it instead of just the first?
– Steve Ng
Dec 25 '13 at 8:12
any solution if I want it to return every elements that matches it instead of just the first?
– Steve Ng
Dec 25 '13 at 8:12
@JohnnyHK, yup, i used it eventually, thanks!
– Steve Ng
Dec 26 '13 at 6:19
@JohnnyHK, yup, i used it eventually, thanks!
– Steve Ng
Dec 26 '13 at 6:19
I'm afraid I am using Mongo 3.0.X :-(
– charliebrownie
Jan 10 '16 at 20:33
I'm afraid I am using Mongo 3.0.X :-(
– charliebrownie
Jan 10 '16 at 20:33
@charliebrownie Then use one of the other answers that use
aggregate.– JohnnyHK
Jan 10 '16 at 21:14
@charliebrownie Then use one of the other answers that use
aggregate.– JohnnyHK
Jan 10 '16 at 21:14
1
1
This also works:
db.test.find(, shapes: $elemMatch: color: "red");– Paul
Jul 14 '17 at 19:15
This also works:
db.test.find(, shapes: $elemMatch: color: "red");– Paul
Jul 14 '17 at 19:15
|
show 3 more comments
The new Aggregation Framework in MongoDB 2.2+ provides an alternative to Map/Reduce. The $unwind operator can be used to separate your shapes array into a stream of documents that can be matched:
db.test.aggregate(
// Start with a $match pipeline which can take advantage of an index and limit documents processed
$match :
"shapes.color": "red"
,
$unwind : "$shapes" ,
$match :
"shapes.color": "red"
)
Results in:
"result" : [
"_id" : ObjectId("504425059b7c9fa7ec92beec"),
"shapes" :
"shape" : "circle",
"color" : "red"
],
"ok" : 1
6
@JohnnyHK: In this case,$elemMatchis another option. I actually got here by way of a Google Group question where $elemMatch wouldn't work because it only returns the first match per document.
– Stennie
Sep 3 '12 at 4:24
1
Thanks, I wasn't aware of that limitation so that's good to know. Sorry for deleting my comment you're responding to, I decided to post another answer instead and didn't want to confuse people.
– JohnnyHK
Sep 3 '12 at 4:35
3
@JohnnyHK: No worries, there are now three useful answers for the question ;-)
– Stennie
Sep 3 '12 at 4:41
For other searchers, in addition to this I also tried adding$project : shapes : 1- which seemed to work and would be helpful if the enclosing documents were large and you just wanted to view theshapeskey values.
– user1063287
Dec 4 '14 at 8:23
2
@calmbird I updated the example to include an initial $match stage. If you're interested in a more efficient feature suggestion I would watch/upvote SERVER-6612: Support projecting multiple array values in a projection like the $elemMatch projection specifier in the MongoDB issue tracker.
– Stennie
Jan 28 '15 at 8:52
|
show 3 more comments
The new Aggregation Framework in MongoDB 2.2+ provides an alternative to Map/Reduce. The $unwind operator can be used to separate your shapes array into a stream of documents that can be matched:
db.test.aggregate(
// Start with a $match pipeline which can take advantage of an index and limit documents processed
$match :
"shapes.color": "red"
,
$unwind : "$shapes" ,
$match :
"shapes.color": "red"
)
Results in:
"result" : [
"_id" : ObjectId("504425059b7c9fa7ec92beec"),
"shapes" :
"shape" : "circle",
"color" : "red"
],
"ok" : 1
6
@JohnnyHK: In this case,$elemMatchis another option. I actually got here by way of a Google Group question where $elemMatch wouldn't work because it only returns the first match per document.
– Stennie
Sep 3 '12 at 4:24
1
Thanks, I wasn't aware of that limitation so that's good to know. Sorry for deleting my comment you're responding to, I decided to post another answer instead and didn't want to confuse people.
– JohnnyHK
Sep 3 '12 at 4:35
3
@JohnnyHK: No worries, there are now three useful answers for the question ;-)
– Stennie
Sep 3 '12 at 4:41
For other searchers, in addition to this I also tried adding$project : shapes : 1- which seemed to work and would be helpful if the enclosing documents were large and you just wanted to view theshapeskey values.
– user1063287
Dec 4 '14 at 8:23
2
@calmbird I updated the example to include an initial $match stage. If you're interested in a more efficient feature suggestion I would watch/upvote SERVER-6612: Support projecting multiple array values in a projection like the $elemMatch projection specifier in the MongoDB issue tracker.
– Stennie
Jan 28 '15 at 8:52
|
show 3 more comments
The new Aggregation Framework in MongoDB 2.2+ provides an alternative to Map/Reduce. The $unwind operator can be used to separate your shapes array into a stream of documents that can be matched:
db.test.aggregate(
// Start with a $match pipeline which can take advantage of an index and limit documents processed
$match :
"shapes.color": "red"
,
$unwind : "$shapes" ,
$match :
"shapes.color": "red"
)
Results in:
"result" : [
"_id" : ObjectId("504425059b7c9fa7ec92beec"),
"shapes" :
"shape" : "circle",
"color" : "red"
],
"ok" : 1
The new Aggregation Framework in MongoDB 2.2+ provides an alternative to Map/Reduce. The $unwind operator can be used to separate your shapes array into a stream of documents that can be matched:
db.test.aggregate(
// Start with a $match pipeline which can take advantage of an index and limit documents processed
$match :
"shapes.color": "red"
,
$unwind : "$shapes" ,
$match :
"shapes.color": "red"
)
Results in:
"result" : [
"_id" : ObjectId("504425059b7c9fa7ec92beec"),
"shapes" :
"shape" : "circle",
"color" : "red"
],
"ok" : 1
edited Jan 28 '15 at 8:41
answered Sep 3 '12 at 3:44
StennieStennie
49.7k8 gold badges118 silver badges144 bronze badges
49.7k8 gold badges118 silver badges144 bronze badges
6
@JohnnyHK: In this case,$elemMatchis another option. I actually got here by way of a Google Group question where $elemMatch wouldn't work because it only returns the first match per document.
– Stennie
Sep 3 '12 at 4:24
1
Thanks, I wasn't aware of that limitation so that's good to know. Sorry for deleting my comment you're responding to, I decided to post another answer instead and didn't want to confuse people.
– JohnnyHK
Sep 3 '12 at 4:35
3
@JohnnyHK: No worries, there are now three useful answers for the question ;-)
– Stennie
Sep 3 '12 at 4:41
For other searchers, in addition to this I also tried adding$project : shapes : 1- which seemed to work and would be helpful if the enclosing documents were large and you just wanted to view theshapeskey values.
– user1063287
Dec 4 '14 at 8:23
2
@calmbird I updated the example to include an initial $match stage. If you're interested in a more efficient feature suggestion I would watch/upvote SERVER-6612: Support projecting multiple array values in a projection like the $elemMatch projection specifier in the MongoDB issue tracker.
– Stennie
Jan 28 '15 at 8:52
|
show 3 more comments
6
@JohnnyHK: In this case,$elemMatchis another option. I actually got here by way of a Google Group question where $elemMatch wouldn't work because it only returns the first match per document.
– Stennie
Sep 3 '12 at 4:24
1
Thanks, I wasn't aware of that limitation so that's good to know. Sorry for deleting my comment you're responding to, I decided to post another answer instead and didn't want to confuse people.
– JohnnyHK
Sep 3 '12 at 4:35
3
@JohnnyHK: No worries, there are now three useful answers for the question ;-)
– Stennie
Sep 3 '12 at 4:41
For other searchers, in addition to this I also tried adding$project : shapes : 1- which seemed to work and would be helpful if the enclosing documents were large and you just wanted to view theshapeskey values.
– user1063287
Dec 4 '14 at 8:23
2
@calmbird I updated the example to include an initial $match stage. If you're interested in a more efficient feature suggestion I would watch/upvote SERVER-6612: Support projecting multiple array values in a projection like the $elemMatch projection specifier in the MongoDB issue tracker.
– Stennie
Jan 28 '15 at 8:52
6
6
@JohnnyHK: In this case,
$elemMatch is another option. I actually got here by way of a Google Group question where $elemMatch wouldn't work because it only returns the first match per document.– Stennie
Sep 3 '12 at 4:24
@JohnnyHK: In this case,
$elemMatch is another option. I actually got here by way of a Google Group question where $elemMatch wouldn't work because it only returns the first match per document.– Stennie
Sep 3 '12 at 4:24
1
1
Thanks, I wasn't aware of that limitation so that's good to know. Sorry for deleting my comment you're responding to, I decided to post another answer instead and didn't want to confuse people.
– JohnnyHK
Sep 3 '12 at 4:35
Thanks, I wasn't aware of that limitation so that's good to know. Sorry for deleting my comment you're responding to, I decided to post another answer instead and didn't want to confuse people.
– JohnnyHK
Sep 3 '12 at 4:35
3
3
@JohnnyHK: No worries, there are now three useful answers for the question ;-)
– Stennie
Sep 3 '12 at 4:41
@JohnnyHK: No worries, there are now three useful answers for the question ;-)
– Stennie
Sep 3 '12 at 4:41
For other searchers, in addition to this I also tried adding
$project : shapes : 1 - which seemed to work and would be helpful if the enclosing documents were large and you just wanted to view the shapes key values.– user1063287
Dec 4 '14 at 8:23
For other searchers, in addition to this I also tried adding
$project : shapes : 1 - which seemed to work and would be helpful if the enclosing documents were large and you just wanted to view the shapes key values.– user1063287
Dec 4 '14 at 8:23
2
2
@calmbird I updated the example to include an initial $match stage. If you're interested in a more efficient feature suggestion I would watch/upvote SERVER-6612: Support projecting multiple array values in a projection like the $elemMatch projection specifier in the MongoDB issue tracker.
– Stennie
Jan 28 '15 at 8:52
@calmbird I updated the example to include an initial $match stage. If you're interested in a more efficient feature suggestion I would watch/upvote SERVER-6612: Support projecting multiple array values in a projection like the $elemMatch projection specifier in the MongoDB issue tracker.
– Stennie
Jan 28 '15 at 8:52
|
show 3 more comments
Caution: This answer provides a solution that was relevant at that time, before the new features of MongoDB 2.2 and up were introduced. See the other answers if you are using a more recent version of MongoDB.
The field selector parameter is limited to complete properties. It cannot be used to select part of an array, only the entire array. I tried using the $ positional operator, but that didn't work.
The easiest way is to just filter the shapes in the client.
If you really need the correct output directly from MongoDB, you can use a map-reduce to filter the shapes.
function map()
filteredShapes = [];
this.shapes.forEach(function (s)
if (s.color === "red")
filteredShapes.push(s);
);
emit(this._id, shapes: filteredShapes );
function reduce(key, values)
return values[0];
res = db.test.mapReduce(map, reduce, query: "shapes.color": "red" )
db[res.result].find()
add a comment |
Caution: This answer provides a solution that was relevant at that time, before the new features of MongoDB 2.2 and up were introduced. See the other answers if you are using a more recent version of MongoDB.
The field selector parameter is limited to complete properties. It cannot be used to select part of an array, only the entire array. I tried using the $ positional operator, but that didn't work.
The easiest way is to just filter the shapes in the client.
If you really need the correct output directly from MongoDB, you can use a map-reduce to filter the shapes.
function map()
filteredShapes = [];
this.shapes.forEach(function (s)
if (s.color === "red")
filteredShapes.push(s);
);
emit(this._id, shapes: filteredShapes );
function reduce(key, values)
return values[0];
res = db.test.mapReduce(map, reduce, query: "shapes.color": "red" )
db[res.result].find()
add a comment |
Caution: This answer provides a solution that was relevant at that time, before the new features of MongoDB 2.2 and up were introduced. See the other answers if you are using a more recent version of MongoDB.
The field selector parameter is limited to complete properties. It cannot be used to select part of an array, only the entire array. I tried using the $ positional operator, but that didn't work.
The easiest way is to just filter the shapes in the client.
If you really need the correct output directly from MongoDB, you can use a map-reduce to filter the shapes.
function map()
filteredShapes = [];
this.shapes.forEach(function (s)
if (s.color === "red")
filteredShapes.push(s);
);
emit(this._id, shapes: filteredShapes );
function reduce(key, values)
return values[0];
res = db.test.mapReduce(map, reduce, query: "shapes.color": "red" )
db[res.result].find()
Caution: This answer provides a solution that was relevant at that time, before the new features of MongoDB 2.2 and up were introduced. See the other answers if you are using a more recent version of MongoDB.
The field selector parameter is limited to complete properties. It cannot be used to select part of an array, only the entire array. I tried using the $ positional operator, but that didn't work.
The easiest way is to just filter the shapes in the client.
If you really need the correct output directly from MongoDB, you can use a map-reduce to filter the shapes.
function map()
filteredShapes = [];
this.shapes.forEach(function (s)
if (s.color === "red")
filteredShapes.push(s);
);
emit(this._id, shapes: filteredShapes );
function reduce(key, values)
return values[0];
res = db.test.mapReduce(map, reduce, query: "shapes.color": "red" )
db[res.result].find()
edited Jul 19 '16 at 18:42
answered Oct 21 '10 at 9:25
Niels van der RestNiels van der Rest
24.1k13 gold badges72 silver badges84 bronze badges
24.1k13 gold badges72 silver badges84 bronze badges
add a comment |
add a comment |
Another interesing way is to use $redact, which is one of the new aggregation features of MongoDB 2.6. If you are using 2.6, you don't need an $unwind which might cause you performance problems if you have large arrays.
db.test.aggregate([
$match:
shapes: $elemMatch: color: "red"
,
$redact :
$cond:
if: $or : [ $eq: ["$color","red"] , $not : "$color" ],
then: "$$DESCEND",
else: "$$PRUNE"
]);
$redact "restricts the contents of the documents based on information stored in the documents themselves". So it will run only inside of the document. It basically scans your document top to the bottom, and checks if it matches with your if condition which is in $cond, if there is match it will either keep the content($$DESCEND) or remove($$PRUNE).
In the example above, first $match returns the whole shapes array, and $redact strips it down to the expected result.
Note that $not:"$color" is necessary, because it will scan the top document as well, and if $redact does not find a color field on the top level this will return false that might strip the whole document which we don't want.
1
perfect answer. As you mentioned $unwind will consume lot of RAM. So this will be better when compared.
– manojpt
Apr 21 '15 at 11:21
I have a doubt. In the example, "shapes" is an array. Will "$redact" scan all the objects in the "shapes" array ?? How this will be good with respect to performance??
– manojpt
Apr 23 '15 at 8:13
not all of it, but the result of your first match. That is the reason why you put$matchas your first aggregate stage
– anvarik
Apr 23 '15 at 16:36
okkk.. if an index created on "color" field, even then it will scan all the objects in the "shapes" array??? Which could be the efficient way of matching multiple objects in an array???
– manojpt
Apr 24 '15 at 4:47
2
Brilliant! I do not understand how $eq works here. I left it off originally and this didn't work for me. Somehow, it looks in the array of shapes to find the match, but the query never specifies which array to look in. Like, if the documents had shapes and, for example, sizes; would $eq look in both arrays for matches? Is $redact just looking for anything within the document that matches the 'if' condition?
– Onosa
Dec 30 '15 at 14:46
|
show 1 more comment
Another interesing way is to use $redact, which is one of the new aggregation features of MongoDB 2.6. If you are using 2.6, you don't need an $unwind which might cause you performance problems if you have large arrays.
db.test.aggregate([
$match:
shapes: $elemMatch: color: "red"
,
$redact :
$cond:
if: $or : [ $eq: ["$color","red"] , $not : "$color" ],
then: "$$DESCEND",
else: "$$PRUNE"
]);
$redact "restricts the contents of the documents based on information stored in the documents themselves". So it will run only inside of the document. It basically scans your document top to the bottom, and checks if it matches with your if condition which is in $cond, if there is match it will either keep the content($$DESCEND) or remove($$PRUNE).
In the example above, first $match returns the whole shapes array, and $redact strips it down to the expected result.
Note that $not:"$color" is necessary, because it will scan the top document as well, and if $redact does not find a color field on the top level this will return false that might strip the whole document which we don't want.
1
perfect answer. As you mentioned $unwind will consume lot of RAM. So this will be better when compared.
– manojpt
Apr 21 '15 at 11:21
I have a doubt. In the example, "shapes" is an array. Will "$redact" scan all the objects in the "shapes" array ?? How this will be good with respect to performance??
– manojpt
Apr 23 '15 at 8:13
not all of it, but the result of your first match. That is the reason why you put$matchas your first aggregate stage
– anvarik
Apr 23 '15 at 16:36
okkk.. if an index created on "color" field, even then it will scan all the objects in the "shapes" array??? Which could be the efficient way of matching multiple objects in an array???
– manojpt
Apr 24 '15 at 4:47
2
Brilliant! I do not understand how $eq works here. I left it off originally and this didn't work for me. Somehow, it looks in the array of shapes to find the match, but the query never specifies which array to look in. Like, if the documents had shapes and, for example, sizes; would $eq look in both arrays for matches? Is $redact just looking for anything within the document that matches the 'if' condition?
– Onosa
Dec 30 '15 at 14:46
|
show 1 more comment
Another interesing way is to use $redact, which is one of the new aggregation features of MongoDB 2.6. If you are using 2.6, you don't need an $unwind which might cause you performance problems if you have large arrays.
db.test.aggregate([
$match:
shapes: $elemMatch: color: "red"
,
$redact :
$cond:
if: $or : [ $eq: ["$color","red"] , $not : "$color" ],
then: "$$DESCEND",
else: "$$PRUNE"
]);
$redact "restricts the contents of the documents based on information stored in the documents themselves". So it will run only inside of the document. It basically scans your document top to the bottom, and checks if it matches with your if condition which is in $cond, if there is match it will either keep the content($$DESCEND) or remove($$PRUNE).
In the example above, first $match returns the whole shapes array, and $redact strips it down to the expected result.
Note that $not:"$color" is necessary, because it will scan the top document as well, and if $redact does not find a color field on the top level this will return false that might strip the whole document which we don't want.
Another interesing way is to use $redact, which is one of the new aggregation features of MongoDB 2.6. If you are using 2.6, you don't need an $unwind which might cause you performance problems if you have large arrays.
db.test.aggregate([
$match:
shapes: $elemMatch: color: "red"
,
$redact :
$cond:
if: $or : [ $eq: ["$color","red"] , $not : "$color" ],
then: "$$DESCEND",
else: "$$PRUNE"
]);
$redact "restricts the contents of the documents based on information stored in the documents themselves". So it will run only inside of the document. It basically scans your document top to the bottom, and checks if it matches with your if condition which is in $cond, if there is match it will either keep the content($$DESCEND) or remove($$PRUNE).
In the example above, first $match returns the whole shapes array, and $redact strips it down to the expected result.
Note that $not:"$color" is necessary, because it will scan the top document as well, and if $redact does not find a color field on the top level this will return false that might strip the whole document which we don't want.
answered Jun 4 '14 at 8:31
anvarikanvarik
3,9804 gold badges30 silver badges49 bronze badges
3,9804 gold badges30 silver badges49 bronze badges
1
perfect answer. As you mentioned $unwind will consume lot of RAM. So this will be better when compared.
– manojpt
Apr 21 '15 at 11:21
I have a doubt. In the example, "shapes" is an array. Will "$redact" scan all the objects in the "shapes" array ?? How this will be good with respect to performance??
– manojpt
Apr 23 '15 at 8:13
not all of it, but the result of your first match. That is the reason why you put$matchas your first aggregate stage
– anvarik
Apr 23 '15 at 16:36
okkk.. if an index created on "color" field, even then it will scan all the objects in the "shapes" array??? Which could be the efficient way of matching multiple objects in an array???
– manojpt
Apr 24 '15 at 4:47
2
Brilliant! I do not understand how $eq works here. I left it off originally and this didn't work for me. Somehow, it looks in the array of shapes to find the match, but the query never specifies which array to look in. Like, if the documents had shapes and, for example, sizes; would $eq look in both arrays for matches? Is $redact just looking for anything within the document that matches the 'if' condition?
– Onosa
Dec 30 '15 at 14:46
|
show 1 more comment
1
perfect answer. As you mentioned $unwind will consume lot of RAM. So this will be better when compared.
– manojpt
Apr 21 '15 at 11:21
I have a doubt. In the example, "shapes" is an array. Will "$redact" scan all the objects in the "shapes" array ?? How this will be good with respect to performance??
– manojpt
Apr 23 '15 at 8:13
not all of it, but the result of your first match. That is the reason why you put$matchas your first aggregate stage
– anvarik
Apr 23 '15 at 16:36
okkk.. if an index created on "color" field, even then it will scan all the objects in the "shapes" array??? Which could be the efficient way of matching multiple objects in an array???
– manojpt
Apr 24 '15 at 4:47
2
Brilliant! I do not understand how $eq works here. I left it off originally and this didn't work for me. Somehow, it looks in the array of shapes to find the match, but the query never specifies which array to look in. Like, if the documents had shapes and, for example, sizes; would $eq look in both arrays for matches? Is $redact just looking for anything within the document that matches the 'if' condition?
– Onosa
Dec 30 '15 at 14:46
1
1
perfect answer. As you mentioned $unwind will consume lot of RAM. So this will be better when compared.
– manojpt
Apr 21 '15 at 11:21
perfect answer. As you mentioned $unwind will consume lot of RAM. So this will be better when compared.
– manojpt
Apr 21 '15 at 11:21
I have a doubt. In the example, "shapes" is an array. Will "$redact" scan all the objects in the "shapes" array ?? How this will be good with respect to performance??
– manojpt
Apr 23 '15 at 8:13
I have a doubt. In the example, "shapes" is an array. Will "$redact" scan all the objects in the "shapes" array ?? How this will be good with respect to performance??
– manojpt
Apr 23 '15 at 8:13
not all of it, but the result of your first match. That is the reason why you put
$match as your first aggregate stage– anvarik
Apr 23 '15 at 16:36
not all of it, but the result of your first match. That is the reason why you put
$match as your first aggregate stage– anvarik
Apr 23 '15 at 16:36
okkk.. if an index created on "color" field, even then it will scan all the objects in the "shapes" array??? Which could be the efficient way of matching multiple objects in an array???
– manojpt
Apr 24 '15 at 4:47
okkk.. if an index created on "color" field, even then it will scan all the objects in the "shapes" array??? Which could be the efficient way of matching multiple objects in an array???
– manojpt
Apr 24 '15 at 4:47
2
2
Brilliant! I do not understand how $eq works here. I left it off originally and this didn't work for me. Somehow, it looks in the array of shapes to find the match, but the query never specifies which array to look in. Like, if the documents had shapes and, for example, sizes; would $eq look in both arrays for matches? Is $redact just looking for anything within the document that matches the 'if' condition?
– Onosa
Dec 30 '15 at 14:46
Brilliant! I do not understand how $eq works here. I left it off originally and this didn't work for me. Somehow, it looks in the array of shapes to find the match, but the query never specifies which array to look in. Like, if the documents had shapes and, for example, sizes; would $eq look in both arrays for matches? Is $redact just looking for anything within the document that matches the 'if' condition?
– Onosa
Dec 30 '15 at 14:46
|
show 1 more comment
Better you can query in matching array element using $slice is it helpful to returning the significant object in an array.
db.test.find("shapes.color" : "blue", "shapes.$" : 1)
$slice is helpful when you know the index of the element, but sometimes you want
whichever array element matched your criteria. You can return the matching element
with the $ operator.
add a comment |
Better you can query in matching array element using $slice is it helpful to returning the significant object in an array.
db.test.find("shapes.color" : "blue", "shapes.$" : 1)
$slice is helpful when you know the index of the element, but sometimes you want
whichever array element matched your criteria. You can return the matching element
with the $ operator.
add a comment |
Better you can query in matching array element using $slice is it helpful to returning the significant object in an array.
db.test.find("shapes.color" : "blue", "shapes.$" : 1)
$slice is helpful when you know the index of the element, but sometimes you want
whichever array element matched your criteria. You can return the matching element
with the $ operator.
Better you can query in matching array element using $slice is it helpful to returning the significant object in an array.
db.test.find("shapes.color" : "blue", "shapes.$" : 1)
$slice is helpful when you know the index of the element, but sometimes you want
whichever array element matched your criteria. You can return the matching element
with the $ operator.
edited Sep 18 '14 at 9:14
Egor Neliuba
11.8k6 gold badges44 silver badges66 bronze badges
11.8k6 gold badges44 silver badges66 bronze badges
answered Sep 18 '14 at 8:35
NarendranNarendran
4424 silver badges7 bronze badges
4424 silver badges7 bronze badges
add a comment |
add a comment |
db.getCollection('aj').find("shapes.color":"red","shapes.$":1)
OUTPUTS
"shapes" : [
"shape" : "circle",
"color" : "red"
]
add a comment |
db.getCollection('aj').find("shapes.color":"red","shapes.$":1)
OUTPUTS
"shapes" : [
"shape" : "circle",
"color" : "red"
]
add a comment |
db.getCollection('aj').find("shapes.color":"red","shapes.$":1)
OUTPUTS
"shapes" : [
"shape" : "circle",
"color" : "red"
]
db.getCollection('aj').find("shapes.color":"red","shapes.$":1)
OUTPUTS
"shapes" : [
"shape" : "circle",
"color" : "red"
]
answered Dec 7 '16 at 6:25
Viral PatelViral Patel
6117 silver badges10 bronze badges
6117 silver badges10 bronze badges
add a comment |
add a comment |
The syntax for find in mongodb is
db.<collection name>.find(query, projection);
and the second query that you have written, that is
db.test.find(
shapes: "$elemMatch": color: "red",
"shapes.color":1)
in this you have used the $elemMatch operator in query part, whereas if you use this operator in the projection part then you will get the desired result. You can write down your query as
db.users.find(
"shapes.color":"red",
_id:0, shapes: $elemMatch : color: "red")
This will give you the desired result.
1
This works for me. However, It appears that"shapes.color":"red"in the query parameter (the first parameter of the find method) is not necessary. You can replace it withand get the same results.
– Erik Olson
May 9 '14 at 20:35
2
@ErikOlson Your suggestion is right in the above case, where we need to find all the document that with red color and to apply the projection on them only. But let's say if somebody requires to find out all the document that have color blue but it should return only those element of that shapes array that have color red. In this case the above query can be referenced by somebody else also..
– Vicky
May 11 '14 at 9:22
This seems to be the easiest, but I can't make it work it. It only returns the first matching subdocument.
– newman
Aug 29 '15 at 23:05
add a comment |
The syntax for find in mongodb is
db.<collection name>.find(query, projection);
and the second query that you have written, that is
db.test.find(
shapes: "$elemMatch": color: "red",
"shapes.color":1)
in this you have used the $elemMatch operator in query part, whereas if you use this operator in the projection part then you will get the desired result. You can write down your query as
db.users.find(
"shapes.color":"red",
_id:0, shapes: $elemMatch : color: "red")
This will give you the desired result.
1
This works for me. However, It appears that"shapes.color":"red"in the query parameter (the first parameter of the find method) is not necessary. You can replace it withand get the same results.
– Erik Olson
May 9 '14 at 20:35
2
@ErikOlson Your suggestion is right in the above case, where we need to find all the document that with red color and to apply the projection on them only. But let's say if somebody requires to find out all the document that have color blue but it should return only those element of that shapes array that have color red. In this case the above query can be referenced by somebody else also..
– Vicky
May 11 '14 at 9:22
This seems to be the easiest, but I can't make it work it. It only returns the first matching subdocument.
– newman
Aug 29 '15 at 23:05
add a comment |
The syntax for find in mongodb is
db.<collection name>.find(query, projection);
and the second query that you have written, that is
db.test.find(
shapes: "$elemMatch": color: "red",
"shapes.color":1)
in this you have used the $elemMatch operator in query part, whereas if you use this operator in the projection part then you will get the desired result. You can write down your query as
db.users.find(
"shapes.color":"red",
_id:0, shapes: $elemMatch : color: "red")
This will give you the desired result.
The syntax for find in mongodb is
db.<collection name>.find(query, projection);
and the second query that you have written, that is
db.test.find(
shapes: "$elemMatch": color: "red",
"shapes.color":1)
in this you have used the $elemMatch operator in query part, whereas if you use this operator in the projection part then you will get the desired result. You can write down your query as
db.users.find(
"shapes.color":"red",
_id:0, shapes: $elemMatch : color: "red")
This will give you the desired result.
edited Jan 31 '14 at 8:19
Jinxcat
4191 gold badge3 silver badges16 bronze badges
4191 gold badge3 silver badges16 bronze badges
answered Dec 22 '13 at 8:14
VickyVicky
4664 silver badges14 bronze badges
4664 silver badges14 bronze badges
1
This works for me. However, It appears that"shapes.color":"red"in the query parameter (the first parameter of the find method) is not necessary. You can replace it withand get the same results.
– Erik Olson
May 9 '14 at 20:35
2
@ErikOlson Your suggestion is right in the above case, where we need to find all the document that with red color and to apply the projection on them only. But let's say if somebody requires to find out all the document that have color blue but it should return only those element of that shapes array that have color red. In this case the above query can be referenced by somebody else also..
– Vicky
May 11 '14 at 9:22
This seems to be the easiest, but I can't make it work it. It only returns the first matching subdocument.
– newman
Aug 29 '15 at 23:05
add a comment |
1
This works for me. However, It appears that"shapes.color":"red"in the query parameter (the first parameter of the find method) is not necessary. You can replace it withand get the same results.
– Erik Olson
May 9 '14 at 20:35
2
@ErikOlson Your suggestion is right in the above case, where we need to find all the document that with red color and to apply the projection on them only. But let's say if somebody requires to find out all the document that have color blue but it should return only those element of that shapes array that have color red. In this case the above query can be referenced by somebody else also..
– Vicky
May 11 '14 at 9:22
This seems to be the easiest, but I can't make it work it. It only returns the first matching subdocument.
– newman
Aug 29 '15 at 23:05
1
1
This works for me. However, It appears that
"shapes.color":"red" in the query parameter (the first parameter of the find method) is not necessary. You can replace it with and get the same results.– Erik Olson
May 9 '14 at 20:35
This works for me. However, It appears that
"shapes.color":"red" in the query parameter (the first parameter of the find method) is not necessary. You can replace it with and get the same results.– Erik Olson
May 9 '14 at 20:35
2
2
@ErikOlson Your suggestion is right in the above case, where we need to find all the document that with red color and to apply the projection on them only. But let's say if somebody requires to find out all the document that have color blue but it should return only those element of that shapes array that have color red. In this case the above query can be referenced by somebody else also..
– Vicky
May 11 '14 at 9:22
@ErikOlson Your suggestion is right in the above case, where we need to find all the document that with red color and to apply the projection on them only. But let's say if somebody requires to find out all the document that have color blue but it should return only those element of that shapes array that have color red. In this case the above query can be referenced by somebody else also..
– Vicky
May 11 '14 at 9:22
This seems to be the easiest, but I can't make it work it. It only returns the first matching subdocument.
– newman
Aug 29 '15 at 23:05
This seems to be the easiest, but I can't make it work it. It only returns the first matching subdocument.
– newman
Aug 29 '15 at 23:05
add a comment |
Thanks to JohnnyHK.
Here I just want to add some more complex usage.
// Document
"_id" : 1
"shapes" : [
"shape" : "square", "color" : "red",
"shape" : "circle", "color" : "green"
]
"_id" : 2
"shapes" : [
"shape" : "square", "color" : "red",
"shape" : "circle", "color" : "green"
]
// The Query
db.contents.find(
"_id" : ObjectId(1),
"shapes.color":"red"
,
"_id": 0,
"shapes" :
"$elemMatch":
"color" : "red"
)
//And the Result
"shapes":[
"shape" : "square",
"color" : "red"
]
add a comment |
Thanks to JohnnyHK.
Here I just want to add some more complex usage.
// Document
"_id" : 1
"shapes" : [
"shape" : "square", "color" : "red",
"shape" : "circle", "color" : "green"
]
"_id" : 2
"shapes" : [
"shape" : "square", "color" : "red",
"shape" : "circle", "color" : "green"
]
// The Query
db.contents.find(
"_id" : ObjectId(1),
"shapes.color":"red"
,
"_id": 0,
"shapes" :
"$elemMatch":
"color" : "red"
)
//And the Result
"shapes":[
"shape" : "square",
"color" : "red"
]
add a comment |
Thanks to JohnnyHK.
Here I just want to add some more complex usage.
// Document
"_id" : 1
"shapes" : [
"shape" : "square", "color" : "red",
"shape" : "circle", "color" : "green"
]
"_id" : 2
"shapes" : [
"shape" : "square", "color" : "red",
"shape" : "circle", "color" : "green"
]
// The Query
db.contents.find(
"_id" : ObjectId(1),
"shapes.color":"red"
,
"_id": 0,
"shapes" :
"$elemMatch":
"color" : "red"
)
//And the Result
"shapes":[
"shape" : "square",
"color" : "red"
]
Thanks to JohnnyHK.
Here I just want to add some more complex usage.
// Document
"_id" : 1
"shapes" : [
"shape" : "square", "color" : "red",
"shape" : "circle", "color" : "green"
]
"_id" : 2
"shapes" : [
"shape" : "square", "color" : "red",
"shape" : "circle", "color" : "green"
]
// The Query
db.contents.find(
"_id" : ObjectId(1),
"shapes.color":"red"
,
"_id": 0,
"shapes" :
"$elemMatch":
"color" : "red"
)
//And the Result
"shapes":[
"shape" : "square",
"color" : "red"
]
edited May 23 '17 at 11:54
Community♦
11 silver badge
11 silver badge
answered Mar 23 '14 at 7:05
EddyEddy
2,06224 silver badges31 bronze badges
2,06224 silver badges31 bronze badges
add a comment |
add a comment |
You just need to run query
db.test.find(
"shapes.color": "red",
shapes: $elemMatch: color: "red");
output of this query is
"_id" : ObjectId("562e7c594c12942f08fe4192"),
"shapes" : [
"shape" : "circle", "color" : "red"
]
as you expected it'll gives the exact field from array that matches color:'red'.
add a comment |
You just need to run query
db.test.find(
"shapes.color": "red",
shapes: $elemMatch: color: "red");
output of this query is
"_id" : ObjectId("562e7c594c12942f08fe4192"),
"shapes" : [
"shape" : "circle", "color" : "red"
]
as you expected it'll gives the exact field from array that matches color:'red'.
add a comment |
You just need to run query
db.test.find(
"shapes.color": "red",
shapes: $elemMatch: color: "red");
output of this query is
"_id" : ObjectId("562e7c594c12942f08fe4192"),
"shapes" : [
"shape" : "circle", "color" : "red"
]
as you expected it'll gives the exact field from array that matches color:'red'.
You just need to run query
db.test.find(
"shapes.color": "red",
shapes: $elemMatch: color: "red");
output of this query is
"_id" : ObjectId("562e7c594c12942f08fe4192"),
"shapes" : [
"shape" : "circle", "color" : "red"
]
as you expected it'll gives the exact field from array that matches color:'red'.
edited Nov 10 '16 at 7:50
azhar
8881 gold badge12 silver badges36 bronze badges
8881 gold badge12 silver badges36 bronze badges
answered Sep 17 '16 at 17:22
Vaibhav PatilVaibhav Patil
6896 silver badges18 bronze badges
6896 silver badges18 bronze badges
add a comment |
add a comment |
along with $project it will be more appropriate other wise matching elements will be clubbed together with other elements in document.
db.test.aggregate(
"$unwind" : "$shapes" ,
"$match" :
"shapes.color": "red"
,
"$project":
"_id":1,
"item":1
)
can you pls describe that this accomplishes with an input and output set?
– Alexander Mills
Nov 24 '15 at 17:13
add a comment |
along with $project it will be more appropriate other wise matching elements will be clubbed together with other elements in document.
db.test.aggregate(
"$unwind" : "$shapes" ,
"$match" :
"shapes.color": "red"
,
"$project":
"_id":1,
"item":1
)
can you pls describe that this accomplishes with an input and output set?
– Alexander Mills
Nov 24 '15 at 17:13
add a comment |
along with $project it will be more appropriate other wise matching elements will be clubbed together with other elements in document.
db.test.aggregate(
"$unwind" : "$shapes" ,
"$match" :
"shapes.color": "red"
,
"$project":
"_id":1,
"item":1
)
along with $project it will be more appropriate other wise matching elements will be clubbed together with other elements in document.
db.test.aggregate(
"$unwind" : "$shapes" ,
"$match" :
"shapes.color": "red"
,
"$project":
"_id":1,
"item":1
)
answered Feb 9 '13 at 15:45
shakthydossshakthydoss
1,5282 gold badges18 silver badges34 bronze badges
1,5282 gold badges18 silver badges34 bronze badges
can you pls describe that this accomplishes with an input and output set?
– Alexander Mills
Nov 24 '15 at 17:13
add a comment |
can you pls describe that this accomplishes with an input and output set?
– Alexander Mills
Nov 24 '15 at 17:13
can you pls describe that this accomplishes with an input and output set?
– Alexander Mills
Nov 24 '15 at 17:13
can you pls describe that this accomplishes with an input and output set?
– Alexander Mills
Nov 24 '15 at 17:13
add a comment |
db.test.find( "shapes.color": "red", _id: 0)
1
Welcome to Stack Overflow! Thank you for the code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by describing why this is a good solution to the problem, and would make it more useful to future readers with other similar questions. Please edit your answer to add some explanation, including the assumptions you've made.
– sepehr
Oct 25 '18 at 15:06
add a comment |
db.test.find( "shapes.color": "red", _id: 0)
1
Welcome to Stack Overflow! Thank you for the code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by describing why this is a good solution to the problem, and would make it more useful to future readers with other similar questions. Please edit your answer to add some explanation, including the assumptions you've made.
– sepehr
Oct 25 '18 at 15:06
add a comment |
db.test.find( "shapes.color": "red", _id: 0)
db.test.find( "shapes.color": "red", _id: 0)
edited Oct 25 '18 at 8:04
Suraj Rao
25.3k8 gold badges65 silver badges76 bronze badges
25.3k8 gold badges65 silver badges76 bronze badges
answered Oct 25 '18 at 8:00
Poonam AgrawalPoonam Agrawal
152 bronze badges
152 bronze badges
1
Welcome to Stack Overflow! Thank you for the code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by describing why this is a good solution to the problem, and would make it more useful to future readers with other similar questions. Please edit your answer to add some explanation, including the assumptions you've made.
– sepehr
Oct 25 '18 at 15:06
add a comment |
1
Welcome to Stack Overflow! Thank you for the code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by describing why this is a good solution to the problem, and would make it more useful to future readers with other similar questions. Please edit your answer to add some explanation, including the assumptions you've made.
– sepehr
Oct 25 '18 at 15:06
1
1
Welcome to Stack Overflow! Thank you for the code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by describing why this is a good solution to the problem, and would make it more useful to future readers with other similar questions. Please edit your answer to add some explanation, including the assumptions you've made.
– sepehr
Oct 25 '18 at 15:06
Welcome to Stack Overflow! Thank you for the code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by describing why this is a good solution to the problem, and would make it more useful to future readers with other similar questions. Please edit your answer to add some explanation, including the assumptions you've made.
– sepehr
Oct 25 '18 at 15:06
add a comment |
protected by Samuel Liew♦ Oct 5 '15 at 9:21
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?