0

I have the following example of data set:

SampleCol.insert({
    Name: "John Doe",
    Description: "Nice Guy",
    Embedded_1: [{
        key1: 'x1',
        key2: 'x2',
        TariffTypes: [{
            TariffCode: 'Promocional',
            Price: 125,
            Weekdays: ['Sun', 'Sat']              
        },
        {
            TariffCode: 'LastMinute',
            Price: 150,
            Weekdays: ['Sun', 'Sat']   
        }], 
        },
        {
        key1: 'x3',
        key2: 'x4',
           TariffTypes: [{
                TariffCode: 'Promocional',
                Price: 175,
                Weekdays: ['Sun', 'Sat']           
            },
            {
                TariffCode: 'LastMinute',
                Price: 200,
                Weekdays: ['Sun', 'Sat']
            }] 
        }]
    });

I am trying to filter and show on my template only Embedded_1 with key1='x1'. Here is the template:

  <template name="test2">
   {{#each items}}
    {{# each Embedded_1}}
        {{this.key1}}
    {{/each}}
   {{/each}} 
  </template>

I tried the following and the Template helper versions:

Version 1 is returning both x1 and x3:

Template.test2.helpers({
  items: function () {
     collection = SampleCol.find({'Embedded_1.key1': 'x1'});
  return collection;
  }
 });

This also returns all results:

       collection = SampleCol.find({Embedded_1: {$elemMatch: { key1: 'x1'}}});

The exit in both cases is: x1x3

It should show only x1.

Where is the error?

EDIT: I have followed answers suggested by Mark Leiber and BraveKenny and they help solve the Mongodb output . I can get now on Mogo shell the desired outcome with the following command:

db.SampleCol.find({},{_id:0, Embedded_1: {$elemMatch: {key1:"x1"}}})

This solves the Mongo part. However, I guess that this problem is also related on HOW this results interact with Meteor Blaze's template. Template "test2" keeps showing up the entire collection rather than what we just filtered.

Any hints there?

EDIT #2 This is indeed a Blaze template issue. The Mongo find() code above correctly returns only the key='x1' results. It even strips out the parent document and data such as name and description:

{
  Embedded_1: [{
        key1: 'x1',
        key2: 'x2',
        TariffTypes: [{
            TariffCode: 'Promocional',
            Price: 125,
            Weekdays: ['Sun', 'Sat']              
        },
        {
            TariffCode: 'LastMinute',
            Price: 150,
            Weekdays: ['Sun', 'Sat']   
        }], 
        };

However, the template only shows any result if written like below, including the {{#each items}} {{/each}} line

 <template name="test2">
   {{#each items}}
    {{Name}} <br>
    {{Description}}<br>
    {{#each Embedded_1}}
       {{this.key1}} <br>
       {{#each TariffTypes}}
            {{this.Price}} <br>
        {{/each}}
   {{/each}}
{{/each}}
</template>

Despite the template helper is not returning Name and Description, it does show them on browser together. It shows like this:

John Doe
Nice Guy
x1 
125 
150 
x3 
175 
200 

I have tester taking out {{#each items}} or {{#each Embedded_1}} and none worked.

How would the Template Blaze should be written?

Juliomac
  • 447
  • 7
  • 15
  • [Interesting read](http://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection) – SylvainB May 29 '15 at 13:24
  • possible duplicate of [MongoDB - Filtering the content of an internal Array in a resultset](http://stackoverflow.com/questions/4701427/mongodb-filtering-the-content-of-an-internal-array-in-a-resultset) – Mark Leiber May 29 '15 at 13:26
  • You are simply finding any document that matches your criteria, so your document is returned. You need to filter the returned content. See the duplicate link I posted. – Mark Leiber May 29 '15 at 13:28
  • The accepted answer there ("Mongo does have this feature implemented") does not seem right. The problem is that Mongo is returning the entire document while I want only the parts that match my find criteria. In Mongodb docs shows several alternatives using don notation, $elemMatch or aggregation. I think aggregation is like using a cannon for a small bug. What is the way to return only document that matches the query? – Juliomac May 29 '15 at 15:51
  • The answer given on the question link [link]http://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection **BraveKenny** gave works nicely at Mongo shell. I finally got ONLY what I wanted to match! Thanks for the link BrakeKenny! Somehow, however, in the browser, the template is still showing x1x3, indicating that it is receiving yet the whole document. Could that be something silly I am doing? – Juliomac May 29 '15 at 16:34

1 Answers1

0

This should return only the embedded document:

SampleCol.find({Embedded_1: {$elemMatch:{key1:'x3'}}}, {fields: {Embedded_1: true}})
Adnan Y
  • 2,982
  • 1
  • 26
  • 29
  • Thanks for the support Adnan Y, but I am getting this on Mono Shell: error: { "$err" : "Can't canonicalize query: BadValue Unsupported projection option: fields: { Embedded_1: true }", "code" : 17287 } and getting this on the browser: [Object Object] – Juliomac Jun 01 '15 at 15:25
  • This was for Meteor. For Mongo, projection operation is slightly different. `db.somecollection.find({Embedded_1: {$elemMatch:{key1:'x3'}}}, {Embedded_1: true})` should work in mongo console. – Adnan Y Jun 01 '15 at 18:45
  • Well, I did wrote db.somecollection.find... on Mogno Shell, of course. This message was a result of that. If I had done as in your first example, the error message would have been "SampleCol is not defined". but the problem seems to be another. It is on how templates on Blaze interact with Mongo find() returns. See my Edit2 on my new findings. – Juliomac Jun 02 '15 at 13:39