Count in Firebase JavaScript - javascript

I have a sample JSON object below:
{
"product" : [ {
"description" : "This ball has air it.",
"id" : "product0",
"name" : "football",
"price" : 10
}, {
"description" : "Can kick upto long distance.",
"id" : "product1",
"name" : "soccer boots",
"price" : 5
}, {
"description" : "Long socks",
"id" : "product2",
"name" : "stockings",
"price" : 2
}, {
"description" : "This ball has air it.",
"id" : "product3",
"name" : "gloves",
"price" : 3
}, {
"description" : "Wear it pls.",
"id" : "product4",
"name" : "jersey",
"price" : 12
} ]
}
What can be the shortest way to find the number (count) of products in JavaScript? Does Firebase provide any query in JavaScript to find the count in an object?

Here is a simple solution. Just get the length of required array from the JSON Object.
var json = {
"product": [{
"description": "This ball has air it.",
"id": "product0",
"name": "football",
"price": 10
}, {
"description": "Can kick upto long distance.",
"id": "product1",
"name": "soccer boots",
"price": 5
}, {
"description": "Long socks",
"id": "product2",
"name": "stockings",
"price": 2
}, {
"description": "This ball has air it.",
"id": "product3",
"name": "gloves",
"price": 3
}, {
"description": "Wear it pls.",
"id": "product4",
"name": "jersey",
"price": 12
}]
};
console.log(json.product.length);
Incase of JSON string: Get the length like this
var json = '{ "product" : [ {"description" : "This ball has air it.","id" : "product0","name" : "football","price" : 10 }, {"description" : "Can kick upto long distance.","id" : "product1","name" : "soccer boots","price" : 5 }, {"description" : "Long socks","id" : "product2","name" : "stockings","price" : 2 }, {"description" : "This ball has air it.","id" : "product3","name" : "gloves","price" : 3 }, {"description" : "Wear it pls.","id" : "product4","name" : "jersey","price" : 12 } ]}';
var t = JSON.parse(json);
console.log(t.product.length);

You can save the object on JavaScript variable
var myData = {
"product" : [ {
"description" : "This ball has air it.",
"id" : "product0",
"name" : "football",
"price" : 10
}, {
"description" : "Can kick upto long distance.",
"id" : "product1",
"name" : "soccer boots",
"price" : 5
}, {
"description" : "Long socks",
"id" : "product2",
"name" : "stockings",
"price" : 2
}, {
"description" : "This ball has air it.",
"id" : "product3",
"name" : "gloves",
"price" : 3
}, {
"description" : "Wear it pls.",
"id" : "product4",
"name" : "jersey",
"price" : 12
} ]
}
Now you can get length
console.log(myData.product.length);

Related

How to group by sub documents and get unique value of value field?

This is my database collection:
{"productId" : 1,
"isVariant": 1,
"isComplete" : 1,
"variantId" : 1,
"attributeSet" : [
{
"name" : "Capacity",
"value" : "500 GB",
"id" : 3
},
{
"name" : "Form Factor",
"value" : "5 inch",
"id" : 4
},
{
"id" : 5,
"name" : "Memory Components",
"value" : "3D NAND",
"isVariation" : 0
}
]
},
{"productId" : 2,
"isVariant": 1,
"isComplete" : 1,
"variantId" : 1,
"attributeSet" : [
{
"name" : "Capacity",
"value" : "1 TB",
"id" : 3
},
{
"name" : "Form Factor",
"value" : "5 inch",
"id" : 4
},
{
"id" : 5,
"name" : "Memory Components",
"value" : "3D NAND",
"isVariation" : 0
}
]
},
{"productId" : 3,
"isVariant": 1,
"isComplete" : 0,
"variantId" : 1,
"attributeSet" : [
{
"name" : "Capacity",
"value" : "500 GB",
"id" : 3
},
{
"name" : "Form Factor",
"value" : "2.5 inch",
"id" : 4
},
{
"id" : 5,
"name" : "Memory Components",
"value" : "3D NAND",
"isVariation" : 0
}
]
},
{"productId" : 4,
"isVariant": 1,
"isComplete" : 0,
"variantId" : 1,
"attributeSet" : [
{
"name" : "Capacity",
"value" : "1 TB",
"id" : 3
},
{
"name" : "Form Factor",
"value" : "2.5 inch",
"id" : 4
},
{
"id" : 5,
"name" : "Memory Components",
"value" : "3D NAND",
"isVariation" : 0
}
]
}
Now I want to send the data of only the attribute where isVariation is not 0. Also I want to send the variant values of each attribute where isComplete =1. Hence the result should look like this
result : [{
"id": 3,
"name": "Capacity",
"value": [
"500 GB",
"1 TB"
]
}, {
"id": 4,
"name": "Form Factor",
"value": [
"5 inch"
]
}]
The above result does not have value of 2.5 inch as the isComplete is 0 for this document. Can anyone help me with the query
$match isComplete is 1
$project to show required fields
$unwind deconstruct attributeSet array
$match attributeSet.isVariation is not 0
$group by attributeSet.id and get first name and get unique value using $addToSet
db.collection.aggregate([
{ $match: { isComplete: 1 } },
{
$project: {
_id: 0,
attributeSet: 1
}
},
{ $unwind: "$attributeSet" },
{ $match: { "attributeSet.isVariation": { $ne: 0 } } },
{
$group: {
_id: "$attributeSet.id",
name: { $first: "$attributeSet.name" },
value: { $addToSet: "$attributeSet.value" }
}
}
])
Playground
The $project stage is not required in your query, i have added because this will optimize your query performance.

How to fetch data in jquery as input for chart?

I would like to use chart.js for creating a couple of charts on my webpage, now the data that I receive from the controller is in the following format,
{
"dataset" : [
{
"name" : "Sarah",
"age" : "23",
"gender" : "female",
"country" : "australia",
"occupation" : "student"
},
{
"name" : "Randy",
"age" : "19",
"gender" : "male",
"country" : "america",
"occupation" : "student"
},
{
"name" : "Roger",
"age" : "32",
"gender" : "male",
"country" : "germany",
"occupation" : "software professional"
},
{
"name" : "Maverick",
"age" : "10",
"gender" : "male",
"country" : "america",
"occupation" : "student"
},
{
"name" : "Riya",
"age" : "25",
"gender" : "female",
"country" : "australia",
"occupation" : "software professional"
},
{
"name" : "Glade",
"age" : "30",
"gender" : "female",
"country" : "India",
"occupation" : "teacher"
}
]
}
Now, I would like to plot this information on 3 pie charts,
1) pie chart that shows the count of country of origin.
2) pie chart that shows the count of occupation.
3) pie chart that shows the count of people who have age less than 25.
So ideally the graph takes in information in the following format,
var pieData = {
graph-data:
[
{
name : country,
dataset : [
{
value: america,
count: 2,
color:"#878BB6"
},
{
value: india,
count : 1,
color : "#4ACAB4"
},
{
value: germany,
count : 1,
color : "#FF8153"
},
{
value: australia,
count : 2,
color : "#FFEA88"
}
]
},
{
name : occupation,
dataset : [
{
value: "student",
count: 3,
color:"#878BB6"
},
{
value: "software professional",
count : 2,
color : "#4ACAB4"
},
{
value: "teacher",
count : 1,
color : "#FF8153"
}
]
},
{
name : "age",
dataset : [
{
value: "23",
count: 1,
color:"#878BB6"
},
{
value: "19",
count : 1,
color : "#4ACAB4"
},
{
value: "10",
count : 1,
color : "#FF8153"
},
{
value: "25",
count : 1,
color : "#FF8423"
}
]
}
]
};
As you can see from the above json, the graph-data key has 3 array elements, each of which corresponds to a chart. How can I construct this data from the initial raw dataset and pass this to my chart.js for consumption? I am guessing I would be requiring to write converters, how can I achieve this in js/jquery, any information on this is highly appreciated. Thanks ahead!

cannot use the part (stats of stats.cat3.detail.name) to traverse the element. nested objects and arrays

I'm able to do
db.getCollection('comps').find({"stats.cat3.detail.name" : "Friendlyness"})`
This shows the proper docs the have a name of "Friendlyness" in the detail array.
I wanted to change "Friendlyness" to "friendliness"
I tried :
db.getCollection('comps').update(
{"stats.cat3.detail.name" : "Friendlyness"},
{$set : {"stats.cat3.detail.name" : "Friendliness"} }
)
and got errors like
" cannot use the part (stats of stats.cat3.detail.name) to traverse the element ({stats: [ { cat3: ...."
I tried putting in position operators "$" all over the update object property. but still get errors.
sample data:
{
"_id" : ObjectId("58d94c441eb9e52454932db6"),
"desc" : "Manufacturer of a wide range of consumer electronics products including audio, video, communications, and computer systems.",
"source" : "alexa",
"category" : "Consumer Electronics",
"name" : "comp1.com",
"__v" : 0,
"stats" : [
{
"cat1" : {
"detail" : [
{
"value" : [
{
"data" : 1,
"name" : "quick service"
}
],
"name" : "Time on hold"
},
{
"value" : [
{
"data" : 1,
"name" : "some words but strong accent"
},
{
"data" : 1,
"name" : "EZ to understand"
}
],
"name" : "Language fluency"
},
{
"value" : [
{
"data" : 1,
"name" : "Yes"
}
],
"name" : "Human answered"
},
{
"value" : [
{
"data" : 2,
"name" : "Like a hot potato"
},
{
"data" : 1,
"name" : "1 or 2 times"
}
],
"name" : "Transfered alot"
},
{
"value" : [
{
"data" : 3,
"name" : "ok time"
},
{
"data" : 1,
"name" : "quick service"
},
{
"data" : 1,
"name" : "short time"
}
],
"name" : "Time on Hold"
},
{
"value" : [
{
"data" : 1,
"name" : "some word but strong accent"
},
{
"data" : 2,
"name" : "EZ to understand"
}
],
"name" : "Language Fluency"
},
{
"value" : [
{
"data" : 2,
"name" : "Yes"
}
],
"name" : "Human Answered"
}
],
"average" : 81
},
"cat2" : {
"detail" : [
{
"value" : [
{
"data" : 1,
"name" : "It was ok"
},
{
"data" : 1,
"name" : "Not EZ at all"
},
{
"data" : 7,
"name" : "there were hidden gimicks"
},
{
"data" : 2,
"name" : "It was OK"
},
{
"data" : 1,
"name" : "Found Quickly"
}
],
"name" : "Easy to find desired product"
},
{
"value" : [
{
"data" : 1,
"name" : "Easy to understand"
},
{
"data" : 1,
"name" : "Eventually understood"
}
],
"name" : "Clear information about the product"
},
{
"value" : [
{
"data" : 2,
"name" : "none"
},
{
"data" : 3,
"name" : "There was but won't complain"
},
{
"data" : 1,
"name" : "Very Bad"
}
],
"name" : "Annoying popups"
},
{
"value" : [
{
"data" : 4,
"name" : "Eventually Understood"
},
{
"data" : 1,
"name" : "EZ to understand"
}
],
"name" : "Clear data about the product"
}
],
"average" : 71
},
"cat3" : {
"detail" : [
{
"value" : [
{
"data" : 1,
"name" : "Very quick"
}
],
"name" : "Prompteness"
},
{
"value" : [
{
"data" : 3,
"name" : "We're cool"
},
{
"data" : 4,
"name" : "They didn't like me"
}
],
"name" : "Friendlyness"
},
{
"value" : [
{
"data" : 3,
"name" : "Very Confusing"
},
{
"data" : 2,
"name" : "Still a little confused"
},
{
"data" : 3,
"name" : "Enlightened"
}
],
"name" : "Knowledge"
},
{
"value" : [
{
"data" : 3,
"name" : "On hold too many times"
}
],
"name" : "Promptness"
}
],
"average" : 69
}
}
]
}

Mongodb aggregate based on past date

I am trying to perform a query in Mongodb. The query I'd like to perform is find all orders in a collection based on date (7 days past), then add up the prices with the nested objects for each order. I have the following code so far:
Collection/Data
{
"_id" : "g32fYpydfSFDbFkoi",
"orderNumber" : 1234,
"createdAt" : ISODate("2016-01-12T13:50:17.559Z"),
"productsInOrder" : [
{
"category" : "ambient",
"item" : 23982,
"desc" : "Ergonomic Cotton Sausages",
"quantity" : "456",
"price" : "0.54",
"lineprice" : "246.24",
"_id" : "BdD4QnM7sYTwBpLds"
},
{
"category" : "ambient",
"item" : 15336,
"desc" : "Rustic Wooden Chicken",
"quantity" : "2",
"price" : "1.87",
"lineprice" : "3.74",
"_id" : "PvtSxi2MfYrZNTD6f"
},
{
"category" : "chilled",
"item" : 57584,
"desc" : "Unbranded Soft Chicken",
"quantity" : "3",
"price" : "4.69",
"lineprice" : "14.07",
"_id" : "ppkECqmhPvg7pQcgB"
},
{
"category" : "ambient",
"item" : 71168,
"desc" : "Rustic Rubber Computer",
"quantity" : "5",
"price" : "3.04",
"lineprice" : "15.20",
"_id" : "bZtr5dkvsG92YtLoe"
},
{
"category" : "frozen",
"item" : 87431,
"desc" : "Unbranded Granite Sausages",
"quantity" : "5678",
"price" : "1.98",
"lineprice" : "11242.44",
"_id" : "ZKur3rHhtCLsWiENr"
},
{
"category" : "frozen",
"item" : 75007,
"desc" : "Practical Frozen Towels",
"quantity" : "678",
"price" : "1.19",
"lineprice" : "806.82",
"_id" : "g78zvzoE8wJkciD9C"
},
{
"category" : "frozen",
"item" : 84721,
"desc" : "Fantastic Metal Hat",
"quantity" : "34",
"price" : "1.83",
"lineprice" : "62.22",
"_id" : "4aqxBWhXy5cabbbiM"
},
{
"category" : "frozen",
"item" : 72240,
"desc" : "Fantastic Granite Towels",
"quantity" : "1",
"price" : "2.94",
"lineprice" : "2.94",
"_id" : "MQD2LNv36mE3BWvZJ"
},
{
"category" : "chilled",
"item" : 89448,
"desc" : "Intelligent Concrete Towels",
"quantity" : "6678",
"price" : "0.42",
"lineprice" : "2804.76",
"_id" : "AjRrxFT4mfpxuciC4"
},
{
"category" : "chilled",
"item" : 57584,
"desc" : "Unbranded Soft Chicken",
"quantity" : "1111",
"price" : "4.69",
"lineprice" : "5210.59",
"_id" : "4yBspve6mBNNzqDnZ"
}
]
}
Query
Orders.aggregate([
{ $match: { 'createdAt': { $gt: pastDate }}},
{ $unwind: '$productsInOrder' },
{
$group: {
_id: null,
price: {
$sum: '$productsInOrder.price'
}
}
}
]);
What I ultimately want is to output the total price per day for the last 7 days. Can anyone help point me in the right direction? Many thanks in advance.
Firstly, the $sum operator will ignore non-numeric values and the productsInOrder.price subdocument field is of String type so it would be best if you convert this to a numeric field.
Having done that, to output the total price per day for the last 7 days, change the group by key to use the $dayOfMonth operator which groups your documents per day within that 7 day range, as in the following
Orders.aggregate([
{ "$match": { "createdAt": { "$gt": pastDate } } },
{ "$unwind": "$productsInOrder" },
{
"$group": {
"_id": {
"day": { "$dayOfMonth": "$createdAt" }
},
"price": { "$sum": "$productsInOrder.price" }
}
}
]);

Mongo query and response 'GroupBy' implementation using Mongoose and/or underscore.js

We have a mongo collection messages that is in the following format...
/* 0 */
{
"text" : "A message to John",
"created" : ISODate("2015-01-29T23:50:10.488Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
/* 1 */
{
"text" : "Another message to John",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin fowler"
},
}
/* 2 */
{
"text" : "Just another message to Jerry",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Jerry Jones"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
/* 2 */
{
"text" : "Message to Martin Fowler",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Martin Fowler"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Jerry Jones"
},
}
We need to display the data above in a conversation format where we group each of the conversations together. A conversation meaning that it can either be to or from.
An example of what we need this to data to look like is the following format:
{
"result":[
{
"id":"54bf1dc6c65b030c00faec0d",
"name":"Jerry Jones",
"messages":[
{
"text" : "A message to John",
"created" : ISODate("2015-01-29T23:50:10.488Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
{
"text" : "Another message to John",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin fowler"
},
}
]
},
{
"id":"54bf1e80eb5bf8800b0f5a8d",
"name":"John Smith",
"messages":[
{
"text" : "Just another message to Jerry",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Jerry Jones"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
{
"text" : "Message to Martin Fowler",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Martin Fowler"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Jerry Jones"
},
}
]
}
]
}
NOTE This query is always made in the context of a current user which is why on each of the conversations, we have an _id and a name which represents the other user in the conversation. For the example above, the current user would be Martin Fowler
We have tried several different ways of accomplishing this, but keep running into issues. Id rather turn to the Mongo/Node community in order to see how it can be done correctly. We are using mongoose with Node if that helps at all...
The initial query implementation that we have currently is the following:
Message.find().or([{'from.id':req.user.id},{'to.id':req.user.id}]).exec(function(err,messages){
//NEED TO IMPLEMENT THIS HERE CORRECTLY
});
NOTE that the req.user.id is the id of the current user
This solution is a slight modification of my previous solution to a similar kind of problem here.
The documents in question have member names in inconsistent cases. Martin Folwer should be Martin Fowler throughout the app/database, and not Martin fowler. (Note the small f). You need to make this change to your documents.
$group messages together, based on the to and from field.
construct a group key - "message_between", with the value being a
$concat result of the values in to and from fields.
Messages from Martin Fowler to Jerry Jones and Jerry Jones to
Martin Fowler should be treated under a single group.To achieve
that, we make the result contain the name coming last
alphabetically, first. So our key for all the Messages from Martin
Fowler to Jerry Jones and Jerry Jones to Martin Fowler would be
Martin Fowler and Jerry Jones.
Code:
Model.aggregate(
//match all those records which involve the user.
{$match:{$or:[{"to.name":req.user.id},
{"from.name":req.user.id}]}},
{$group:{"_id":{
"message_between":{
$cond:[
{
$gt:[
{$substr:["$to.name",0,1]},
{$substr:["$from.name",0,1]}]
},
{$concat:["$to.name"," and ","$from.name"]},
{$concat:["$from.name"," and ","$to.name"]}
]
},"name":{$cond:[{$eq:["$to.name",
req.user.id]},
"$from.name",
"$to.name"]}
},"messages":{$push:"$$ROOT"}
}
},
{$project:{"_id":0,"name":"$_id.name","messages":1}}
,function(err,resp){
// handle response.
})
o/p:
{
"messages" : [
{
"_id" : ObjectId("54d1d819b62f332e93fbb906"),
"text" : "Just another message to Jerry",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Jerry Jones"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
}
},
{
"_id" : ObjectId("54d1d819b62f332e93fbb907"),
"text" : "Message to Martin Fowler",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Martin Fowler"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Jerry Jones"
}
}
],
"name" : "Jerry Jones"
}
{
"messages" : [
{
"_id" : ObjectId("54d1d819b62f332e93fbb904"),
"text" : "A message to John",
"created" : ISODate("2015-01-29T23:50:10.488Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
}
},
{
"_id" : ObjectId("54d1d819b62f332e93fbb905"),
"text" : "Another message to John",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
}
}
],
"name" : "John Smith"
}
I tried to create a mongo request for you, but i'm not sure it's relevant...
I can generate almost exactly the same format as you need in one request:
db.messages.aggregate([{$match:{$or:[{"from.id":ObjectId("54bf1dc6c65b030c00faec0d")},{"to.id":ObjectId("54bf1dc6c65b030c00faec0d")}]}},{$group:{_id: ObjectId("54bf1dc6c65b030c00faec0d"), messages:{$push: "$$ROOT"}}}]);
The probleme is, you still need to specify the id, i'm not sure it's what you need.
Using this I get the following result:
{
"_id": ObjectId("54bf1dc6c65b030c00faec0d"),
"messages": [
{
"_id": ObjectId("54d1b9f02cd45cae7e453633"),
"text": "A message to John",
"created": ISODate("2015-01-29T23:50:10.488Z"),
"to": {
"id": ObjectId("54bf1dc6c65b030c00faec0d"),
"name": "John Smith"
},
"from": {
"id": ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name": "Martin Fowler"
}
},
{
"_id": ObjectId("54d1ba052cd45cae7e453634"),
"text": "Another message to John",
"created": ISODate("2015-01-30T00:37:38.106Z"),
"to": {
"id": ObjectId("54bf1dc6c65b030c00faec0d"),
"name": "John Smith"
},
"from": {
"id": ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name": "Martin fowler"
}
}
]
}
I'm not using mongoose so I can't help you with this part, but with "mongodb" module, this query can be used directly, so it should be possible with mongoose too.

Categories