how to fetch the element present inside Json Object through mongodb query - node.js

I am using mongodb database, I unable to apply query to fetch all document with status CERTIFIED,I am using below document, please suggets any query like to fetch all document with "status":"CERTIFIED"
{
"_id" : ObjectId("592fb37d57693963cca325e5"),
"json" : {
"query_by_gtin_response:queryByGtinResponse" : {
"productData" : {
"gtin" : "31212121212167",
"productDataRecord" : {
"module" : [
{
"bpi:basicProductInformationModule" : {
"xmlns:bpi" : "urn:gs1:tsd:basic_product_information_module:xsd:1",
"productName" : {
"languageCode" : "en",
"value" : "test"
},
"brandNameInformation" : {
"brandName" : {
"value" : "test pub"
}
}
}
},
{
"product_tracking_information_module" : {
"variantId" : {
"value" : "31124ff0-4693-11e7-9492-01c27f5bdb71"
},
"status" : {
"value" : "CERTIFIED"
},
"name" : {
"value" : "admin#gmail.com"
},
"createdBy" : {
"value" : "552f5b90b348147e03e49b62"
},
"createdDate" : {
"value" : "2017-06-01T06:26:05.551Z"
},
"updatedBy" : {
"value" : "552f5b90b348147e03e49b62"
},
"updatedDate" : {
"value" : "2017-06-01T06:26:05.551Z"
},
"applicationId" : {
"value" : "webapp"
},
"history" : {
"createdDate" : {
"value" : "2017-06-01T06:26:05.551Z"
},
"updatedDate" : {
"value" : "2017-06-01T06:26:05.551Z"
},
"status" : {
"value" : "CERTIFIED"
},
"updatedBy" : {
"value" : "552f5b90b348147e03e49b62"
},
"createdBy" : {
"value" : "552f5b90b348147e03e49b62"
},
"applicationId" : {
"value" : "webapp"
},
"name" : {
"value" : "admin#gmail.com"
}
}
}
}
]
}
}
}
}
}

You can use a function as your $where operator:
collection.find({ $where: function() {
var productDataRecord = this.json["query_by_gtin_response:queryByGtinResponse"]["productData"]["productDataRecord"];
var status = productDataRecord["module"][1]["product_tracking_information_module"].status;
return (status.value == "CERTIFIED")
}})

Related

Mongo update to many query

does anyone know how to change a propertie value in mongo
from
i changed JSON.units[0].services[0].label from etiket controle to AuditLabel
i tried this:
db.getCollection('assortiment').updateMany({"units.$[].services.$[].label": "etiket controle"},{ "$set": { "units.$[].services.$[].label": "AuditLabel" }})
but no succes because it dont select anything
{
"_id" : "764",
"meta" : {
"groupsId" : "764",
"type" : "DRYGR"
},
"units" : [
{
"unit" : "BASE_UNIT_OR_EACH",
"gtin" : "08711728556206",
"services" : [
{
"label" : "etiket controle",
"collection" : "gtins"
}
]
}
]
}
to
{
"_id" : "764",
"meta" : {
"groupsId" : "764",
"type" : "DRYGR"
},
"units" : [
{
"unit" : "BASE_UNIT_OR_EACH",
"gtin" : "08711728556206",
"services" : [
{
"label" : "AuditLabel",
"collection" : "gtins"
}
]
}
]
}
Try this code its work's for me
db.getCollection('assortiment').updateMany(
{
"units.services.label": "etiket controle"
},
{
"$set":
{ "units.$[].services.$[].label": "AuditLabel" }
}
)

nodeJS mongoose how to make a special get crud

That's my mongodb data base shown in cmd as you see there is a field named test which exist a time and one other time didn't exist I want to write a get method to find field which contain only imei without test
router.get('/', (req, res, next) => {
Post.find()
.then((posts) => {
res.json(posts);
console.log(posts);
console.log("ok" + JSON.stringify(req.body) + req.body.imei);
})
.catch(err => console.log(err))
});
Here the get method it show me all data base I want to customize it.
{
"_id" : ObjectId("5eb6b927e1c2916320ab28de"),
"imei" : {
"name" : "50"
},
"test" : {
"batterieState" : "0"
},
"__v" : 0
}
{
"_id" : ObjectId("5eb6bbbc09183a3e4c833ebe"),
"imei" : {
"name" : "xx"
},
"__v" : 0
}
{
"_id" : ObjectId("5eb6bbcb09183a3e4c833ebf"),
"imei" : {
"name" : ""
},
"__v" : 0
}
{
"_id" : ObjectId("5eb6bc7809183a3e4c833ec0"),
"imei" : {
"name" : "865566048694354"
},
"__v" : 0
}
{
"_id" : ObjectId("5eb6bcc309183a3e4c833ec1"),
"imei" : {
"name" : "865566048694354"
},
"__v" : 0
}
{
"_id" : ObjectId("5eb6bd1209183a3e4c833ec2"),
"imei" : {
"name" : "865566048694354"
},
"__v" : 0
}
{
"_id" : ObjectId("5eb6bdc609183a3e4c833ec3"),
"imei" : {
"name" : "865566048694354"
},
"__v" : 0
}
{
"_id" : ObjectId("5eb6be4609183a3e4c833ec4"),
"imei" : {
"name" : "xx"
},
"test" : {
"tactileState" : "0",
"pixelState" : "0",
"greyState" : "0"
},
"__v" : 0
}
{
"_id" : ObjectId("5eb6be6609183a3e4c833ec5"),
"imei" : {
"name" : "865566048694354"
},
"__v" : 0
}
{
"_id" : ObjectId("5eb6beef09183a3e4c833ec6"),
"imei" : {
"name" : "xx"
},
"test" : {
"tactileState" : "0",
"pixelState" : "0",
"greyState" : "0"
},
"__v" : 0
}
{
"_id" : ObjectId("5eb6bf8709183a3e4c833ec7"),
"imei" : {
"name" : "865566048694354"
},
"test" : {
"tactileState" : "ignore",
"pixelState" : "ignore",
"greyState" : "ignore"
},
"__v" : 0
}
I want some help for this to write this method correctly to get only fields with imei only and without test.
Use this query
Post.find({
imei: {
$exists: true
},
test: {
$exists: false
}
})
Docs of $exists operator

Need to apply two group in sequence and second group should will have effect on result of first group

I want to group my data on the base of factoryId field and then each factory there will be multiple orders want to again group on basis of orderId as each order can contain multiple items. Here I am giving the example of my data and what I need and first group by which I tried.
{
"_id" : ObjectId("5b3e270c42d8004cea382e87"),
"factoryId" : ObjectId("5aa76190cef23a1561b8056c"),
"productId" : ObjectId("5aa78c66cef23a1561b80893"),
"orderId" : ObjectId("5b3e270c42d8004cea382e86"),
"generatedOrderId" : "3985-166770-4554",
"productName" : "Lakme Lotion"
},
{
"_id" : ObjectId("5b3e270c42d8004cea382e88"),
"factoryId" : ObjectId("5b39aed32832f72062e51c23"),
"productId" : ObjectId("5b3cb96139cec8341df52c4b"),
"orderId" : ObjectId("5b3e270c42d8004cea382e86"),
"generatedOrderId" : "3985-166770-4554",
"productName" : "Coke"
},
{
"_id" : ObjectId("5b3e27b07fe0d94d62b76b2a"),
"factoryId" : ObjectId("5aa76190cef23a1561b8057c"),
"productId" : ObjectId("5ac21075ac347a5fbf355028"),
"orderId" : ObjectId("5b3e27b07fe0d94d62b76b27"),
"generatedOrderId" : "3985-755507-7484",
"productName" : "Spoon"
}
And I want result as:
{
"factoryId":ObjectId("5aa76190cef23a1561b8057c"),
"orders":[
{
"orderId":ObjectId("5b3e270c42d8004cea382e86")
"items":[
{
"productName":"Lakme Lotion"
},
{
"productName":"Coke"
}
]
}
]
}
Can anyone help me with this?. Any help is appreciated.
I tried and It worked for me. Sorry
db.getCollection("transactions").aggregate(
[
{
"$group" : {
"_id" : "$orderId",
"items" : {
"$push" : "$$ROOT"
}
}
},
{
"$project" : {
"orderId" : "$_id",
"items" : "$items",
"_id" : 0
}
},
{
"$unwind" : {
"path" : "$items",
"preserveNullAndEmptyArrays" : false
}
},
{
"$group" : {
"_id" : "$items.factoryId",
"orders" : {
"$push" : "$$ROOT"
}
}
},
{
"$project" : {
"factoryId" : "$_id",
"orders" : "$orders",
"_id" : 0
}
}
]
);

How can I check if my aggregate query is good or bad?

How can I check if my aggregate query is good or bad? I already use "explain" but it's not specific.
Here's the output of my aggregate "explain".
{
"waitedMS" : NumberLong(0),
"stages" : [
{
"$cursor" : {
"query" : {
"keys.license_id" : ObjectId("580eeb7fb79bec95648775a2"),
"deleted.status" : {
"$ne" : 1
}
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "serpentsmsapp.conversations",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"keys.license_id" : {
"$eq" : ObjectId("580eeb7fb79bec95648775a2")
}
},
{
"$not" : {
"deleted.status" : {
"$eq" : 1
}
}
}
]
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [
{
"keys.license_id" : {
"$eq" : ObjectId("580eeb7fb79bec95648775a2")
}
},
{
"$not" : {
"deleted.status" : {
"$eq" : 1
}
}
}
]
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
}
}
},
{
"$sort" : {
"sortKey" : {
"_id" : 1,
"keys.license_id" : 1,
"status.deleted" : 1
}
}
},
{
"$lookup" : {
"from" : "conversation_messages",
"as" : "cmf",
"localField" : "_id",
"foreignField" : "keys.conv_id",
"unwinding" : {
"preserveNullAndEmptyArrays" : false
}
}
},
{
"$match" : {
"cmf.deleted.status" : 0
}
},
{
"$sort" : {
"sortKey" : {
"cmf.deleted.status" : -1
}
}
},
{
"$group" : {
"_id" : {
"id" : "$_id",
"number" : "$number",
"mode" : "$mode",
"keys" : "$keys",
"ports" : "$ports",
"user_assign" : "$user_assign",
"spam" : "$spam"
},
"cm_field" : {
"$last" : {
"id" : "$cmf._id",
"message" : "$cmf.message",
"ports" : "$cmf.ports",
"mode" : "$cmf.mode",
"keys" : "$cmf.keys",
"status" : "$cmf.status",
"date" : "$cmf.updated"
}
},
"counts" : {
"$sum" : "$cmf.status"
},
"sms_mode" : {
"$addToSet" : "$cmf.mode"
}
}
},
{
"$sort" : {
"sortKey" : {
"cm_field.date" : -1
},
"limit" : NumberLong(5000)
}
},
{
"$group" : {
"_id" : "$_id",
"cm_field" : {
"$last" : "$cm_field"
},
"counts" : {
"$first" : "$counts"
},
"sms_mode" : {
"$first" : "$sms_mode"
}
}
}
],
"ok" : 1
}
How can I see how many docs are scanned before performing my query?
In order to solve your problem I suggest you the following plan
Learn how does Explain work.
"Good or bad" approach is not an engineering approach, it always depends on a lot of factors (requirements, hardware, etc...). You should define what are those requirements before answering if it query is performant enough.
For your specific explain log. "COLSCAN" - means it has used all your documents on the collection to aggregate the result, this usually is an alert sign, you should think of using proper indexes.

How to fetch specific fields in Mongo DB only values without keys?

My data set is following:
{ "_id" : "EVNQUERY-k9Uoo74Q3WcdmU", "event_data" : "{\"data\":\"helo\"}", "event_name" : "onOemPushAlert", "timestamp_start" : 1452678481433, "timestamp_end" : 1452678481433, "sender" : "USR-ADMIN", "status" : "pending", "query" : { "user" : { "and" : [ { "email" : { "eq" : "" } } ] } }, "updated_on" : ISODate("2016-01-13T09:48:01.459Z"), "created_on" : ISODate("2016-01-13T09:48:01.459Z") }
{ "_id" : "EVNQUERY-yAKmrbzs2JeaUY", "event_data" : "{\"data\":\"ji\"}", "event_name" : "onOemPushAlert", "timestamp_start" : 1452681060159, "timestamp_end" : 1452681060159, "sender" : "USR-ADMIN", "status" : "pending", "query" : { "user" : { "###and###" : [ { "email" : { "eq" : "" } } ] } }, "updated_on" : ISODate("2016-01-13T10:31:00.223Z"), "created_on" : ISODate("2016-01-13T10:31:00.223Z") }
{ "_id" : "EVNQUERY-0NeCstt2eJchDZ", "event_data" : "{\"data\":\"hyg\"}", "event_name" : "onOemPushAlert", "timestamp_start" : 1452681073882, "timestamp_end" : 1452681073882, "sender" : "USR-ADMIN", "status" : "pending", "query" : { "user" : { "###and###" : [ { "email" : { "eq" : "" } } ] } }, "updated_on" : ISODate("2016-01-13T10:31:13.897Z"), "created_on" : ISODate("2016-01-13T10:31:13.897Z") }
and i am running following query
db.eventqueries.find({},{_id:1})
but it give me
{ "_id" : "EVNQUERY-k9Uoo74Q3WcdmU" }
{ "_id" : "EVNQUERY-yAKmrbzs2JeaUY" }
{ "_id" : "EVNQUERY-0NeCstt2eJchDZ" }
but what i want is
["EVNQUERY-k9Uoo74Q3WcdmU", "EVNQUERY-yAKmrbzs2JeaUY", "EVNQUERY-0NeCstt2eJchDZ"]
Perform a distinct() query against the _id field on the collection:
db.eventqueries.distinct("_id")
In the node.js driver run the distinct() command which would have a callback with the results:
collection.distinct("_id", function(err, docs) {
if (err) { /* handle error */ };
console.log(docs);
});
You can use aggregation to achieve what you want. You can try this out
db.eventqueries.aggregate([
{
$group : {
keys : { $push : "_id" }
}
}
])

Resources