0

anyone know how to return the document with only matched sub-document in javascript?

e.g. here is the database records:

[
  {"name":"bestbuy",notes:["article IT", "article 2"]},
  {"name":"microsoft",notes:["article IT", "another IT", "article 5"]},
  {"name":"IBM",notes:["article 8", "article 9"]}
]

here is my query:

collection.find({"company.notes":/IT/}, function(err,result){})

result is:

[
  {"name":"bestbuy",notes:["article IT", "article 2"]},
  {"name":"microsoft",notes:["article IT", "another IT", "article 5"]},
]

but my expected result is:

[
  {"name":"bestbuy",notes:["article IT"]},
  {"name":"microsoft",notes:["article IT", "another IT"]}
]

any idea? thanks

styvane
  • 59,869
  • 19
  • 150
  • 156
aaron
  • 1,951
  • 3
  • 27
  • 41
  • possible duplicate of [Retrieve only the queried element in an object array in MongoDB collection](http://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection) – Blakes Seven Aug 08 '15 at 08:11
  • thanks, it is more javascript specific i think – aaron Aug 10 '15 at 05:59

1 Answers1

2

You can use aggregation

db.collection.aggregate([
    {$match: {"notes": /IT/}}, 
    {$unwind: "$notes"}, 
    {$match: {notes: /IT/}}, 
    {$group: {_id: '$_id', name: {$first: '$name'}, notes: {$push: '$notes'}}},
    {$project: {'name': 1, 'notes': 1, _id: 0}}
])

yields:

{ "name" : "microsoft", "notes" : [ "article IT", "another IT" ] }
{ "name" : "bestbuy", "notes" : [ "article IT" ] }
styvane
  • 59,869
  • 19
  • 150
  • 156
  • thanks, I did not try because I found the db schema is different, so I updated my question. would you please shed a light on that? – aaron Aug 10 '15 at 02:46
  • and another question: why need to use 2 "$match"s? – aaron Aug 10 '15 at 02:47
  • @aaron This is the answer to you first question. If your db schema is different accept the answer and **ask** a new question. You should not create a [chameleon](http://meta.stackexchange.com/questions/43478/exit-strategies-for-chameleon-questions) question. – styvane Aug 10 '15 at 05:28
  • Then I tried, and the code throws, a headache.. Output is: collection opened D:\Test\node_modules\mongodb\lib\mongodb\connection\base.js:246 throw message; ^ TypeError: object is not a function at D:\Test\node_modules\mongodb\lib\mongodb\collection\aggregation.js:317:7 – aaron Aug 10 '15 at 05:58
  • var results = collection.aggregate([ {$match: {"notes": /IT/}}, {$unwind: "$notes"}, {$match: {notes: /IT/}}, {$group: {_id: '$_id', name: {$first: '$name'}, notes: {$push: '$notes'}}}, {$project: {'name': 1, 'notes': 1, _id: 0}}]); – aaron Aug 10 '15 at 06:02
  • Hi, @aaron I'm having one question if notes are `zero` then that entire object is not returned! I want it to be returned like `{ "name" : "Microsoft", "notes" : [ ] }` in the result. How to achieve this? – Rajath Oct 07 '19 at 12:04