JSON parse eror from query SELECT Mongoose in NodeJS - javascript

I have data from schema "notification" in Mongoose like this :
{
"_id" : ObjectId("5c141ef2a7c50a773661772d"),
"title" : "MY POny",
"message" : "message POny",
"token" : "dHvoi4DQAMw:APA91bFGwBjDRCaOFaodRlgrVLKPLsXRlCymce5an_POCC5WlluOCbCbHWmXr2BvPqifdirxcSOwGJky-BBSyvDqj0ojwSrqDKrBHB0KwyNcZm2l-YHBpVkBlIOwfoiQkZsXZlFOxVj6",
"os" : "ANDROID",
"dateCreated" : ISODate("2018-12-14T14:21:51.834Z"),
"dateUpdated" : ISODate("2018-12-14T14:21:51.834Z"),
"deleted" : false,
"payload" : {
"type" : "PROMO",
"data" : {
"message" : "blabalbla…",
"url" : "https://www.pony.com/pony.png",
"datetime" : "2018-02-06 17:00"
}
},
"mobile" : "123456789101",
"id" : 171,
"__v" : 0,
"response" : {
"multicast_id" : 4.83405561199415e+18,
"success" : 1,
"failure" : 0,
"canonical_ids" : 0,
"results" : [
{
"message_id" : "0:1544822514686455%29669a5329669a53"
}
]
}
}
i have query like this
let getListNotif = await NOTIF.find({mobile : mobile, 'payload.type' : {$ne : 'TRANSACTION'}}).sort({'dateCreated': -1}).limit(limit)
i want to output like this :
let notifShow ={
mobile : getListNotif.mobile,
payload : getListNotif.payload
}
why error json parse in node js when i want send like this :
res.status(200).json(notifShow)

fix done
try {
let getListNotif = await NOTIF.find({'token' : token, 'payload.type' : {$ne : 'TRANSACTION'}}).sort({'dateCreated': -1}).limit(limit)
let array = []
let notifShow = {}
for(let i = 0; i < getListNotif.length; i++){
notifShow = {
mobile : getListNotif[i].mobile,
payload : getListNotif[i].payload
}
array.push(notifShow)
}
res.status(200).json(array)
} catch (error) {
logger.error(error.message)
res.status(422).json(Object.assign({message: error.message}, params))
}

Related

Mongoose aggregate query working as a mongodb query but not able to convert to mongoose

Below is my JSON structure
[{
"_id" : ObjectId("626204345ae3d8ec53ef41ee"),
"categoryName" : "Test Cate",
"__v" : 0,
"createdAt" : ISODate("2022-04-22T01:26:11.627Z"),
"items" : [
{
"itemName" : "Cate",
"user" : ObjectId("6260729af547915d9d876c23"),
"itemDescription" : "slkkndanslk",
"itemImage" : "/images/camping-table.jpeg",
"_id" : ObjectId("626204339b24b2ead6c05a70"),
"updatedAt" : ISODate("2022-04-22T01:26:11.627Z"),
"createdAt" : ISODate("2022-04-22T01:26:11.627Z")
}
],
"updatedAt" : ISODate("2022-04-22T01:26:11.627Z")
},
{
"_id" : ObjectId("62620e725ae3d8ec53ef4aa8"),
"categoryName" : "sdsad",
"__v" : 0,
"createdAt" : ISODate("2022-04-22T02:09:54.028Z"),
"items" : [
{
"itemName" : "asdada",
"user" : ObjectId("62620e6299145edb95147482"),
"itemDescription" : "asdsadad",
"itemImage" : "/images/camping-table.jpeg",
"_id" : ObjectId("62620e7299145edb95147486"),
"updatedAt" : ISODate("2022-04-22T02:09:54.028Z"),
"createdAt" : ISODate("2022-04-22T02:09:54.028Z")
},
{
"itemName" : "dsdsa",
"user" : ObjectId("62620e6299145edb95147482"),
"itemDescription" : "adasdad",
"itemImage" : "/images/camping-table.jpeg",
"_id" : ObjectId("62621b9c3662e0b4acabb71f"),
"updatedAt" : ISODate("2022-04-22T03:06:04.727Z"),
"createdAt" : ISODate("2022-04-22T03:06:04.727Z")
}
],
"updatedAt" : ISODate("2022-04-22T03:06:04.727Z")
}]
This is just one document and there would be array of documents. Also there may be multiple items within the same category.
I want to fetch all the items in all category with a particular userid. In MongoDB below is my query which is giving correct output on mongo shell
db.trades.aggregate([
{
$unwind: "$items"
},
{
$match: {
"items.user": ObjectId("6260729af547915d9d876c23")
}
}
]).pretty()
In mongoose I am doing the following thing but not getting the result
tradeModel.aggregate([ { $unwind : "$items" }, { $match : { "items.user" : id } } ])
.then(res => {
console.log(JSON.stringify(res))
})
Let me know what I am missing
Your parameter id is type string but mongodb store type ObjectId
change
tradeModel.aggregate([ { $unwind : "$items" }, { $match : { "items.user" : id } } ])
.then(res => {
console.log(JSON.stringify(res))
})
into
tradeModel.aggregate([ { $unwind : "$items" }, { $match : { "items.user" : {"$oid": id} } } ])
.then(res => {
console.log(JSON.stringify(res))
})
Got the answer we can use ObjectId(id) in search like this
tradeModel.aggregate([ { $unwind : "$items" }, { $match : { "items.user" : ObjectId(id) } } ])
.then(res => {
console.log(JSON.stringify(res))
})

How to extract data from Firebase realtime database JSON-export

I have a Firebase realtime-database export-json that has nested informations, that I would like to extract. The structure of the JSON looks like this:
{
"users" : {
"024w97mv8NftGFY8THfQIU6PhaJ3" : {
"email" : "xxx",
"id" : "024w97mv8NftGFY8THfQIU6PhaJ3",
"name" : "xxx",
"items" : {
"-LQL9n-r9BGdo3HJZ2sk" : {
"disliked" : true,
"id" : 396,
"name" : "Aaa"
},
"-LQL9oO63nH-QW2w6zz0" : {
"liked" : true,
"id" : 3674,
"name" : "Bbb"
}
}
},
"0ERLT5DLRvbZUnjlnM7Ow0qItpz2" : {
"email" : "zzz",
"id" : "0ERLT5DLRvbZUnjlnM7Ow0qItpz2",
"name" : "zzz",
"items" : {
"-LIZnriSVQMzqTsPFNYa" : {
"id" : 396,
"liked" : true,
"name" : "Aaa"
},
"-LIZnrzOuk4WyjqEiLG8" : {
"disliked" : true,
"id" : 4805,
"name" : "Ccc"
}
}
}
}
}
What I need to achieve is getting a list of all liked item-names, and ideally counting how often an item is liked.
Is there a simple tool or script to do that? Ruby or Javascript would be preferred. Thanks a lot!
You can parse your JSON data in ruby like below
result_hash = JSON.parse(result)
result_ary = result_hash["users"].collect do |k,v|
v["items"].values.select{|v1| v1["liked"] == true }
end
result_data = result_ary.flatten
result of parsing
=> [{"liked"=>true, "id"=>3674, "name"=>"Bbb"}, {"id"=>396, "liked"=>true, "name"=>"Aaa"}]
Now its very easy for getting your required result
result_data.collect{|x| x["name"] }
=> ["Bbb", "Aaa"]
result_data.count {|x| x["name"] == "Aaa"}
=> 1
result_data.count {|x| x["name"] == "Bbb"}
=> 1

Mongoose (MongoDB) - Error: Can't use $each with Number

I've to push a given array of Number values into a selected Document inside my MongoDB database.
The Document that I'm going to update as the following structure:
{
"_id" : {
"id" : 17,
"type" : "f"
},
"__v" : 0,
"created_at" : ISODate("2017-03-22T11:16:21.403Z"),
"token" : {
"expDate" : ISODate("2017-12-31T00:00:00Z"),
"token" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6ImFsYWRpbkBjb25zb3J6aW9jZXIuaXQiLCJleHAiOjE1MTQ2Nzg0MDB9.QvbT146bA_KH5XA7MH8ASXm9cr3sPZChJ3prYyDireI"
},
"updated_at" : ISODate("2017-07-24T09:42:33.741Z"),
"plots" : {
"idPlot" : [
23570,
23475
]
},
"machines" : [
{
"idPlotBind" : 1,
"ip" : "",
"mac" : "18-5F-00-4A-FE-F4",
"irrId" : 31,
"_id" : ObjectId("59084f527d634d301338aac6"),
"addr" : "pialadin.ddns.net"
},
{
"idPlotBind" : null,
"ip" : "",
"mac" : "12-01-02-FE-AB-B2",
"irrId" : 35,
"_id" : ObjectId("59084f7d7d634d301338aac7")
}
]
}
I'm using the Mongoose library for JS, and the accused query is this one:
userSchema.findOneAndUpdate({$and:[{ '_id.id': resData.PlotRows.IdUser}, {'_id.type': 'f'}]},{$addToSet:{'plots.$.idPlot': {$each: plotData}}}, {upsert: false}, function(err, usr){
if(err){
console.log(err);
return;
}
});
But when I try to execute it, gives me back:
Error: Can't use $each with Number

How to query single document which contains specific value of some element in array of arrays MongoDB

I have an document that contains array of arrays i am using embedded document in MongoDb.Say i have collection name Orders looks like:-
"_id" : "HjPGrdkffg7dQPtiX",
"ListOrdersResult" : [
{
"Orders" : {
"Order" : [
{
"LatestShipDate" : "2016-01-13T18:29:59Z",
"OrderType" : "StandardOrder",
"PurchaseDate" : "2016-01-11T10:24:49Z",
"PaymentExecutionDetail" : {
"PaymentExecutionDetailItem" : {
"PaymentMethod" : "COD",
"Payment" : {
"CurrencyCode" : "INR",
"Amount" : "839.30"
}
}
},
"BuyerEmail" : "vccdbptpx2ssd74882#marketplace.amazon.in",
"AmazonOrderId" : "402-4031538-7451469",
"LastUpdateDate" : "2016-01-14T06:47:17Z",
"ShipServiceLevel" : "IN Exp Dom 2",
"NumberOfItemsShipped" : "1",
"OrderStatus" : "Shipped",
"SalesChannel" : "Amazon.in",
"ShippedByAmazonTFM" : "false",
"LatestDeliveryDate" : "2016-01-19T18:29:59Z",
"NumberOfItemsUnshipped" : "0",
"BuyerName" : "xyz",
"EarliestDeliveryDate" : "2016-01-13T18:30:00Z",
"OrderTotal" : {
"CurrencyCode" : "INR",
"Amount" : "839.30"
},
"IsPremiumOrder" : "false",
"EarliestShipDate" : "2016-01-11T18:30:00Z",
"MarketplaceId" : "A21TJRRWUN4KGVC",
"FulfillmentChannel" : "MFN",
"TFMShipmentStatus" : "Delivered",
"PaymentMethod" : "COD",
"ShippingAddress" : {
"StateOrRegion" : "HARYANA",
"City" : "GURGAON",
"Phone" : "9999999999",
"CountryCode" : "IN",
"PostalCode" : "122001",
"Name" : "Murthy",
"AddressLine1" : "House No. , J Block, Badshahpur"
},
"IsPrime" : "false",
"ShipmentServiceLevelCategory" : "Expedited"
},
{
"LatestShipDate" : "2016-01-13T18:29:59Z",
"OrderType" : "StandardOrder",
"PurchaseDate" : "2016-01-11T13:16:49Z",
"PaymentExecutionDetail" : {
"PaymentExecutionDetailItem" : {
"PaymentMethod" : "COD",
"Payment" : {
"CurrencyCode" : "INR",
"Amount" : "899.40"
}
}
},
"BuyerEmail" : "xyz#marketplace.amazon.in",
"AmazonOrderId" : "402-2142159-5087541",
"LastUpdateDate" : "2016-01-14T06:47:15Z",
"ShipServiceLevel" : "IN Exp Dom 2",
"NumberOfItemsShipped" : "1",
"OrderStatus" : "Cancel",
"SalesChannel" : "Amazon.in",
"ShippedByAmazonTFM" : "false",
"LatestDeliveryDate" : "2016-01-19T18:29:59Z",
"NumberOfItemsUnshipped" : "0",
"BuyerName" : "demo prakash",
"EarliestDeliveryDate" : "2016-01-13T18:30:00Z",
"OrderTotal" : {
"CurrencyCode" : "INR",
"Amount" : "899.40"
},
"IsPremiumOrder" : "false",
"EarliestShipDate" : "2016-01-11T18:30:00Z",
"MarketplaceId" : "A21TJEUUN4WGV",
"FulfillmentChannel" : "MFN",
"TFMShipmentStatus" : "Delivered",
"PaymentMethod" : "COD",
"ShippingAddress" : {
"StateOrRegion" : "DELHI",
"City" : "DELHI",
"Phone" : "99999999",
"CountryCode" : "IN",
"PostalCode" : "110038",
"Name" : "Demo prakash",
"AddressLine1" : "Hn 638 gali n 04 Wazirabad new delhi"
},
"IsPrime" : "false",
"ShipmentServiceLevelCategory" : "Expedited"
},
}
]
},
"CreatedBefore" : "2015-03-19T06:17:59Z"
}
],
"ResponseMetadata" : {
"RequestId" : "cf94645e-ada7-4ec6-b161-a97d07a77817"
},
"seller_user_id" : "yg4e34ccodzf3GPR2",
}
So as you can see this is the single document that contains the whole data of array i want to fetch the orders whose status is cancel from this order array.
So for that i have use :-
var orderDetails =
orders.find({"ListOrdersResult.Orders.Order":{$elemMatch:
{ OrderStatus:"Canceled"}}}).fetch();
Also i tried with:-
orders.find({"ListOrdersResult.Orders.Order.OrderStatus":'Canceled'}).fetch();
So this will return the whole document that contains status as canceled and other as well but i want only selected result from the document that contains status as pending.
So is there any way in mongoDb to query a selected value from a single document that contains nested array of arrays as object.
Or I need to staore the values into diff diff documents thats only the solution.
Any help would be appriciated please contribute
Thanks!
You can go with any meteor aggregate package. You can use match and then group the data then send it to client-side.Like :
var ordersLines = orders.aggregate([
{$unwind : "$ListOrdersResult.Orders.Order"},
{$match : { OrderStatus:"Canceled"} },
{$project : {
OrderType : '$ListOrdersResult.Orders.Order.OrderType'
....
}
}
]);
return ordersLines;
But I suggest you go with a different document.

How select data with given condition

I have following data.
{
"name" : "Maria",
"facebook" : [
{
"data" : "fb.com",
"privacy" : true
}
],
"twitter" : [
{
"data" : "twitter.com",
"privacy" : false
}
],
"google" : [
{
"data" : "google.com",
"privacy" : true
}
],
"phno" : [
{
"data" : "+1-1289741824124",
"privacy" : true
}
]
}
I want to return only data having privacy is equal to true. How do I do it ?
I tried but it returns all data having privacy is equal to false also. How do I query the data ?
Please post MongoDB query not Javascript code.
Thanks!
edit
having structure like this:
{
"_id" : ObjectId("575e4c8731dcfb59af388e1d"),
"name" : "Maria",
"providers" : [
{
"type" : "facebook",
"data" : "fb.com",
"privacy" : true
},
{
"type" : "twitter",
"data" : "twitter.com",
"privacy" : false
},
{
"type" : "google",
"data" : "google.com",
"privacy" : true
},
{
"type" : "phno",
"data" : "+1-1289741824124",
"privacy" : true
}
]
}
with query like this:
db.maria.aggregate([{
$project : {
_id : 1,
name : 1,
"providers" : {
$filter : {
input : "$providers",
as : "p",
cond : {
$eq : ["$$p.privacy", true]
}
}
}
}
}
])
])
we are gaining dynamic output, and we don't need to take care about provider name as this is covered by generic structure
{
"providers" : [
{
"type" : "facebook",
"data" : "fb.com",
"privacy" : true
},
{
"type" : "google",
"data" : "google.com",
"privacy" : true
},
{
"type" : "phno",
"data" : "+1-1289741824124",
"privacy" : true
}
],
"name" : "Maria"
}
end of edit
The way you could get this is using aggregation framework.
As we have an array for each field, we need to unwind it first, then we can use $project to set field value or simply null. As this looks like a simple query, it could give a bit of trouble. The way we can improve that is change a document structure, to have an array of providers and simple providerType field.
Aggregation stages below:
db.maria.find()
var unwindFb = {
$unwind : "$facebook"
}
var unwindtw = {
$unwind : "$twitter"
}
var unwindgo = {
$unwind : "$google"
}
var unwindph = {
$unwind : "$phno"
}
var project = {
$project : {
_id : 1,
name : 1, // list other fields here
facebook : {
$cond : {
if : {
$gte : ["$facebook.privacy", true]
},
then : [{
data : "$facebook.data",
privacy : "$facebook.privacy"
}
],
else : null
}
},
twitter : {
$cond : {
if : {
$gte : ["$twitter.privacy", true]
},
then : [{
data : "$twitter.data",
privacy : "$twitter.privacy"
}
],
else : null
}
},
google : {
$cond : {
if : {
$gte : ["$google.privacy", true]
},
then : [{
data : "$google.data",
privacy : "$google.privacy"
}
],
else : null
}
},
phno : {
$cond : {
if : {
$gte : ["$phno.privacy", true]
},
then : [{
data : "$phno.data",
privacy : "$phno.privacy"
}
],
else : null
}
}
}
}
db.maria.aggregate([unwindFb, unwindtw, unwindgo, unwindph, project])
then output looks like this:
{
"_id" : ObjectId("575df49d31dcfb59af388e1a"),
"name" : "Maria",
"facebook" : [
{
"data" : "fb.com",
"privacy" : true
}
],
"twitter" : null,
"google" : [
{
"data" : "google.com",
"privacy" : true
}
],
"phno" : [
{
"data" : "+1-1289741824124",
"privacy" : true
}
]
}
you can use the below code to iterate the object and check for the privacy true
var list = {
"name" : "Maria",
"facebook" : [
{
"data" : "fb.com",
"privacy" : true
}
],
"twitter" : [
{
"data" : "twitter.com",
"privacy" : false
}
],
"google" : [
{
"data" : "google.com",
"privacy" : true
}
],
"phno" : [
{
"data" : "+1-1289741824124",
"privacy" : true
}
]
}
$.each(Object.keys(list), function(index,value){
if(list[value][0].privacy)
{
console.log(list[value][0]);
}
});
If you are open to use lodash ...this is how you can do it...
var tmp = {
...you json here
}
var res =[];//result array of filtered data
_.forIn(tmp, function (o) {
if (Array.isArray(o)) {
if (o[0].privacy === true) {
res.push(o);
}
}
});

Categories