Order by on Angularjs - angularjs-1.6

I need to create a table which is ordered based on the given attribute. It does not work this way. How can i solve it?
$scope.values = {
"sales" : [ {
"jeans" : {
"quantity" : "163811",
"order" : 2
},
"shoes" : {
"quantity" : "101",
"order" : 1
},
"trousers" : {
"quantity" : "10733",
"order" : 3
}]
};
And the view:
<table>
<tr ng-repeat="item in values | orderBy:'order'">
<td>{{item.jeans.quantity}}</td>
<td>{{item.shoes.quantity}}</td>
<td>{{item.trousers.quantity}}</td>
</tr>
</table>
How should order by be orderBy:'item.[what_is_needed].order'
thanks

For this array:
$scope.products = [
{
item: {
quantity: 163811
}
}, {
item: {
quantity: 150
}
}, {
item: {
quantity: 350
}
}
];
You can use the following syntax:
<tr ng-repeat="product in products | orderBy:'item.quantity':true">
See the full answer here

Related

Create MongoDb view contain find clause

Imagine I have a collection named user with below fields
- name
- family
- age
and I want to create a view that return all users that are 19 and 21
try
db.createView( "viewName", "collection", [
{ $match : { key : value } }
,...
,...
])
OK let's start by adding some data to a users collection, lets have a few people at diffrent ages:
> db.users.insertMany([
... { "name": "foo", age: 12 },
... { "name": "bar", age: 19 },
... { "name": "wibble", age: 20 },
... { "name": "wobble", age: 21 }
... ]);
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5bd18277289332325f377fff"),
ObjectId("5bd18277289332325f378000"),
ObjectId("5bd18277289332325f378001"),
ObjectId("5bd18277289332325f378002")
]
}
We can then write a view on top of this collection using the createView method which takes in a aggregation pipeline:
> var pipelines = [ { "$match" : { "$or" : [ { "age" : 19 }, { "age" :21 } ] } } ];
> db.createView("users19and21", "users", pipelines);
{ "ok" : 1 }
If you want to test your pipeline out before creating the view you can just call the aggregate method on the users collection, for example:
> var pipelines = [ { "$match" : { "$or" : [ { "age" : 19 }, { "age" :21 } ] } } ];
> db.users.aggregate(pipelines);
{ "_id" : ObjectId("5bd18277289332325f378000"), "name" : "bar", "age" : 19 }
{ "_id" : ObjectId("5bd18277289332325f378002"), "name" : "wobble", "age" : 21 }
Once we have our view we can just query it like a collection:
> db.users19and21.find()
{ "_id" : ObjectId("5bd18277289332325f378000"), "name" : "bar", "age" : 19 }
{ "_id" : ObjectId("5bd18277289332325f378002"), "name" : "wobble", "age" : 21 }
More information on creating views in mongodb can be found on their documentation - https://docs.mongodb.com/manual/reference/method/db.createView/

Mongodb - Group by Array element

I am trying to group my JSON data using the element inside array.
I think db.collection.aggregate will work. But I need to write custom function (reduce function) instead of built-in aggregation operators/expressions. Any suggestions?
Sample data:
{
"name" : "Person Name",
"age" : 50,
"expense" : [
{
"category" : "food",
"date" : "2017-01-01",
"amount" : 100
},
{
"category" : "travel",
"date" : "2017-01-02",
"amount" : 200
}
]
}
My code:
db.collection.group({
key: { "expense.category": 1 },
initial: { total : 0 },
reduce: function( curr, result ) {
result.total += curr.amount;
}
})
where, key: { "expense.category": 1 } does not work for me.

How can I aggregate nested documents?

I have a collection :
{
_id : xxx,
children : [
{
childrenOfChildren : [
{
price : xxx
},
{
price : xxx
},
{
price : xxx
}
]
},
{
childrenOfChildren : [
{
price : xxx
},
{
price : xxx
},
{
price : xxx
}
]
},
{
childrenOfChildren : [
{
price : xxx
},
{
price : xxx
},
{
price : xxx
}
]
}
]
},
{
_id : xxx,
children : [
{
childrenOfChildren : [
{
price : xxx
},
{
price : xxx
},
{
price : xxx
}
]
},
{
childrenOfChildren : [
{
price : xxx
},
{
price : xxx
},
{
price : xxx
}
]
},
{
childrenOfChildren : [
{
price : xxx
},
{
price : xxx
},
{
price : xxx
}
]
}
]
},
{
_id : xxx,
children : [
{
childrenOfChildren : [
{
price : xxx
},
{
price : xxx
},
{
price : xxx
}
]
},
{
childrenOfChildren : [
{
price : xxx
},
{
price : xxx
},
{
price : xxx
}
]
},
{
childrenOfChildren : [
{
price : xxx
},
{
price : xxx
},
{
price : xxx
}
]
}
]
},
{
_id : xxx,
children : [
{
childrenOfChildren : [
{
price : xxx
},
{
price : xxx
},
{
price : xxx
}
]
},
{
childrenOfChildren : [
{
price : xxx
},
{
price : xxx
},
{
price : xxx
}
]
},
{
childrenOfChildren : [
{
price : xxx
},
{
price : xxx
},
{
price : xxx
}
]
}
]
}
Every entry has an array named children. And Every entry in children has an array named childrenOfChildren. And every entry in childrenOfChildren has an attribute named price. I wanna get maximum value of price in this overall collection. How can I achieve this? Please help me!
you can do this using $unwind and $group.
db.collection.aggregate([
{
$unwind:"$children"
},
{
$unwind:"$children.childrenOfChildren"
},
{
$group:{
_id:null,
maxPrice:{
$max:"$children.childrenOfChildren.price"
}
}
}
])
output:
{ "_id" : null, "maxPrice" : 110 }
try it online: mongoplayground.net/p/sBTclni0YSw
you can get maximum price from overall collection by using aggregate query with $unwind and $group.
can try this query:
db.getCollection('collectionName').aggregate([
{$unwind: "$children"},
{$unwind: "$children.childrenOfChildren"},
{$group:{_id: null, price:{$max: "$children.childrenOfChildren.price"}}}
])

How to Group mongodb - mapReduce output?

i have a query regarding the mapReduce framework in mongodb, so i have a result of key value pair from mapReduce function , now i want to run the query on this output of mapReduce.
So i am using mapReduce to find out the stats of user like this
db.order.mapReduce(function() { emit (this.customer,{count:1,orderDate:this.orderDate.interval_start}) },
function(key,values){
var sum =0 ; var lastOrderDate;
values.forEach(function(value) {
if(value['orderDate']){
lastOrderDate=value['orderDate'];
}
sum+=value['count'];
});
return {count:sum,lastOrderDate:lastOrderDate};
},
{ query:{status:"DELIVERED"},out:"order_total"}).find()
which give me output like this
{ "_id" : ObjectId("5443765ae4b05294c8944d5b"), "value" : { "count" : 1, "orderDate" : ISODate("2014-10-18T18:30:00Z") } }
{ "_id" : ObjectId("54561911e4b07a0a501276af"), "value" : { "count" : 2, "lastOrderDate" : ISODate("2015-03-14T18:30:00Z") } }
{ "_id" : ObjectId("54561b9ce4b07a0a501276b1"), "value" : { "count" : 1, "orderDate" : ISODate("2014-11-01T18:30:00Z") } }
{ "_id" : ObjectId("5458712ee4b07a0a501276c2"), "value" : { "count" : 2, "lastOrderDate" : ISODate("2014-11-03T18:30:00Z") } }
{ "_id" : ObjectId("545f64e7e4b07a0a501276db"), "value" : { "count" : 15, "lastOrderDate" : ISODate("2015-06-04T18:30:00Z") } }
{ "_id" : ObjectId("54690771e4b0070527c657ed"), "value" : { "count" : 6, "lastOrderDate" : ISODate("2015-06-03T18:30:00Z") } }
{ "_id" : ObjectId("54696c64e4b07f3c07010b4a"), "value" : { "count" : 1, "orderDate" : ISODate("2014-11-18T18:30:00Z") } }
{ "_id" : ObjectId("546980d1e4b07f3c07010b4d"), "value" : { "count" : 4, "lastOrderDate" : ISODate("2015-03-24T18:30:00Z") } }
{ "_id" : ObjectId("54699ac4e4b07f3c07010b51"), "value" : { "count" : 30, "lastOrderDate" : ISODate("2015-05-23T18:30:00Z") } }
{ "_id" : ObjectId("54699d0be4b07f3c07010b55"), "value" : { "count" : 1, "orderDate" : ISODate("2014-11-16T18:30:00Z") } }
{ "_id" : ObjectId("5469a1dce4b07f3c07010b59"), "value" : { "count" : 2, "lastOrderDate" : ISODate("2015-04-29T18:30:00Z") } }
{ "_id" : ObjectId("5469a96ce4b07f3c07010b5e"), "value" : { "count" : 1, "orderDate" : ISODate("2014-11-16T18:30:00Z") } }
{ "_id" : ObjectId("5469c1ece4b07f3c07010b64"), "value" : { "count" : 9, "lastOrderDate" : ISODate("2015-04-15T18:30:00Z") } }
{ "_id" : ObjectId("5469f422e4b0ce7d5ee021ad"), "value" : { "count" : 5, "lastOrderDate" : ISODate("2015-06-01T18:30:00Z") } }
......
Now i want to run query and group the users on the basis of count in different categories like for user with count less than 5 in one group , 5-10 in another, etc
and want output something like this
{userLessThan5: 9 }
{user5to10: 2 }
{user10to15: 1 }
{user15to20: 0 }
....
Try this,
db.order.mapReduce(function() { emit (this.customer,{count:1,orderDate:this.orderDate.interval_start}) },
function(key,values){
var category; // add this new field
var sum =0 ; var lastOrderDate;
values.forEach(function(value) {
if(value['orderDate']){
lastOrderDate=value['orderDate'];
}
sum+=value['count'];
});
// at this point you are already aware in which category your records lies , just add a new field to mark it
if(sum < 5){ category: userLessThan5};
if(sum >= 5 && sum <=10){ category: user5to10};
if(sum <= 10 && sum >= 15){ category: user10to15};
if(sum <= 15 && sum >=20){ category: user15to20};
....
return {count:sum,lastOrderDate:lastOrderDate,category:category};
},
{ query:{status:"DELIVERED"},out:"order_total"}).find()
db.order_total.aggregate([{ $group: { "_id": "$value.category", "users": { $sum: 1 } } }]);
you will get you desired result
{userLessThan5: 9 }
{user5to10: 2 }
{user10to15: 1 }
{user15to20: 0 }
....
I wrote a query using your data in aggregation as per my knowledge, there may be better way to solve this problem.
var a=db.test.aggregate([{$match:{"value.count":{$lt:5}}},
{ $group: { _id:"$value.count",total:{"$sum":1}}},
{$group:{_id:"less than 5",total:{$sum:"$total"}}}])
var b=db.test.aggregate([{$match:{"value.count":{$lt:10,$gt:5}}},
{ $group: { _id:"$value.count",total:{"$sum":1}}},
{$group:{_id:"between 5 and 10",total:{$sum:"$total"}}}])
var c=db.test.aggregate([{$match:{"value.count":{$lt:15,$gt:10}}},
{ $group: { _id:"$value.count",total:{"$sum":1}}},
{$group:{_id:"between 10 and 15",total:{$sum:"$total"}}}])
insert a, b, c into another collection
You could try to group the output data after mapreduce to every 5 interval count through aggregate like below
db.data.aggregate([
{ "$group": {
"_id": {
"$subtract": [
{ "$subtract": [ "$value.count", 0 ] },
{ "$mod": [
{ "$subtract": [ "$value.count", 0 ] },
5
]}
]
},
"count": { "$sum": 1 }
}}
])
Also maybe here is one related question here.

Group by subdocument field using aggregation framework

The structure is the following:
{
"_id" : "79f00e2f-5ff6-42e9-a341-3d50410168de",
"bookings" : [
{
"name" : "name1",
"email" : "george_bush#gov.us",
"startDate" : ISODate("2013-12-31T22:00:00Z"),
"endDate" : ISODate("2014-01-09T22:00:00Z")
},
{
"name" : "name2",
"email" : "george_bush#gov.us",
"startDate" : ISODate("2014-01-19T22:00:00Z"),
"endDate" : ISODate("2014-01-24T22:00:00Z")
}
],
"name" : "Hotel0",
"price" : 0,
"rating" : 2
}
Now, I want to generate a report telling me how many bookings were made, grouped by booking month (assume that only booking start date matters) and also grouped by hotels rating.
I expect the answer to be like that:
{
{
rating: 0,
counts: {
month1: 10,
month2: 20,
...
month12: 7
}
}
{
rating: 1,
counts: {
month1: 5,
month2: 8,
...
month12: 9
}
}
...
{
rating: 6,
counts: {
month1: 22,
month2: 23,
...
month12: 24
}
}
}
I tried this with aggregation framework but I'm a little bit stuck.
The following query:
db.book.aggregate([
{ $unwind: '$bookings' },
{ $project: { bookings: 1, rating: 1, month: { $month: '$bookings.startDate' } } },
{ $group: { _id: { rating: '$rating', month: '$month' }, count: { $sum: 1 } } }
]);
Will give you the result per rating/month, but it does not make a subdocument for months. In general, you can not convert a value (such as the month nr) to a key (such as month1)—this is something you can probably quite easily handle in your application though.
The above aggregation results in:
"result" : [
{
"_id" : {
"rating" : 2,
"month" : 1
},
"count" : 1
},
{
"_id" : {
"rating" : 2,
"month" : 12
},
"count" : 1
}
],
"ok" : 1