Reputation: 343
I am new to MongoDB and would like to use Meteor Templates to display the queried data in a table.
I have a collection named "infoData" with this structure:
First Document:
{
"_id" : "A-89273498720",
"myItems" : [
{
"itemId" : "item_1",
"username" : "Homer",
"purpose" : "justBecause",
},
{
"itemId" : "item_2",
"username" : "March",
"purpose" : "justBecause2",
},
{
"itemId" : "item_3",
"username" : "Maggie",
"purpose" : "justBecause3",
}
]
}
Second Document:
{
"_id" : "B-564548461117",
"myItems" : [
{
"itemId" : "item_4",
"username" : "Lisa",
"purpose" : "justBecause4",
},
{
"itemId" : "item_5",
"username" : "Lisa",
"purpose" : "justBecause5",
},
{
"itemId" : "item_6",
"username" : "Bart",
"purpose" : "justBecause5",
}
]
}
Now I need to retrieve "itemId" as well as "username" and "purpose" with the "itemId" as a query operator. The "itemId" is unique. My first problem is to get the data. For example I tried this to get the single "itemId" field "item_2":
infoData.findOne({"myItems.itemId": "item_2"}, {_id: 0, 'myItems.$': 1})
which gets the same result as
infoData.findOne(
{
'myItems.itemId': "item_2"
},
{
'_id': 0, 'myItems': {$elemMatch: {'itemId': "item_2"}}
})
I am unsure if this is the result I need, because when I put this query in JSON.stringify() to see the data in the console I see all fields and objects within the array of the doc which contains "item_2" and not only the data "item_2" of the field "itemId". A possibility to get all fields "itemId", "username" and "purpose" of the query (only the object containing item_2) so that I can iterate over it later in a table would also work for me.
The second issue is that I need to display the data in a table.
So I wrote this helper:
'itemInfoDisplay': function() {
if (Meteor.userId()) {
var itemInfos= infoData.findOne(
{"myItems.itemId": "item_2"}, {_id: 0, 'myItems.$': 1});
return itemInfos
}
}
and want to show the data in a table:
{{#each itemInfoDisplay}}
{{#each myItems}}
<tr>
<td><h4>{{ itemId }}</h4></td>
</tr>
{{/each}}
{{/each}}
I know there is something wrong with the code and also with the HTML template. I guess that the result of the mongoDB query is not an array? Is it possible to make it to one? Is the used mongo query the correct solution for my needs?
At the end I just need to get all data which is assigned to a specific "itemId" and display it in a table. I would appreciate anything that helps.
Upvotes: 0
Views: 1057
Reputation: 843
I can think of two ways to do this. The first is to use a projection as mentioned in this post: Retrieve only the queried element in an object array in MongoDB collection
However, it appears you're using that $elemMatch format. If it's not working, not sure if you want to try find() rather than findOne(). There may be a difference in the way Meteor is sending the query to mongodb.
If that doesn't work, the second way is a little bit of a hack but will work. We take advantage of the fact that findOne (unlike find) is synchronous on the client. So we can get the record, then manually do a forEach to only get the appropriate array elements and return that array. Something like this:
var itemInfos= infoData.findOne({"myItems.itemId": "item_2"}, {_id: 0, 'myItems.$': 1});
var items = [];
itemInfos.myItems.forEach(function(myItem) {
if (myItem.itemId == "item_2") {
items.push(myItem);
};
});
return items;
If you use lodash, you can skip the forEach loop and use filter:
return( _.filter(itemInfos.myItems, {itemId: "item_2"}) );
The ideal way would be to restrict the data at the query level, but if that doesn't work option 2 should.
Upvotes: 1