I want to do a count on an array. This my model
modelDetail.aggregate([
{
$group: {
_id: '$main_section.dept',
count: {$sum: 'first_array.second_array.main_data'}
}
}
], function (err, result) {
if (err) {
//next(err);
console.log(err);
} else {
console.log(JSON.stringify(result));
res.json(result);
}
});
This is bringing out 0 for all the result. Output is below
[{"_id":"design","count":0},
{"_id":"training","count":0},
{"_id":"forecast","count":0},
{"_id":"internal audit","count":0},
{"_id":"research","count":0}]
I wanted to get the count of all the data
this is my schema
var userSchema = mongoose.Schema({
main_section :{
dept : String
},
first_array :[{//
floor : String,
second_array :[{//3rd level
name : String,//4th level
date : String
}]
}]
});
this is the data in the json
{ "_id" : "5bb39baf40f87f17f01734f8",
"main_section" : {
"dept" : "design"
},
"first_array" : [{ "_id" : "5bb39baf40f87f17f01734fc", "floor" : "2nd floor" ,
"second_array" : [
{ "_id" : "5bc102f6dff41a0e844dd2b7", "name" : "Blake Tyson", "date" : "2018-10-12T00:00:00Z" },
{ "_id" : "5bc102fddff41a0e844dd2bb", "name" : "Meagan Shawn", "date" : "2018-10-12T00:00:00Z" },
{ "_id" : "5bc1044dbba8b31ed42e7408", "name" : "Stephen Stone", "date" : "2018-10-12T00:00:00Z" }
]
}]
},
{ "_id" : "5bb39baf40f87f17f01734f8",
"main_section" : {
"dept" : "training"
},
"first_array" : [{ "_id" : "5bb39baf40f87f17f01734fc", "floor" : "1st floor",
"second_array" : [
{ "_id" : "5bc102f6dff41a0e844dd2b7", "name" : "Micheal Harrison", "date" : "2018-10-12T00:00:00Z" },
{ "_id" : "5bc102fddff41a0e844dd2bb", "name" : "Favour Reality", "date" : "2018-10-12T00:00:00Z" },
{ "_id" : "5bc1044dbba8b31ed42e7108", "name" : "Gift Myers", "date" : "2018-10-12T00:00:00Z" },
{ "_id" : "5bc1044dbba8b31ed42e71a1", "name" : "Drake Hills", "date" : "2018-10-12T00:00:00Z" },
{ "_id" : "5bc1044dbba8b31ed42e74c2", "name" : "Hashtan Priest", "date" : "2018-10-12T00:00:00Z" }
]
}]
},
{ "_id" : "5b98987f08925c0f5cd86780",
"main_section" : {
"dept" : "forecast"
},
"first_array" : [{ "_id" : "5b98987f08925c0f5cd86784", "floor" : "4th floor",
"second_array" : [ ]
}]
},
{ "_id" : "5b98187f08924c0f5ad86790",
"main_section" : {
"dept" : "internal audit"
},
"first_array" : [{ "_id" : "5b98987f08925c0f5cd86784", "floor" : "4th floor",
"second_array" : [ ]
}]
},
{ "_id" : "5b98187f08924c0f5ad86790",
"main_section" : {
"dept" : "research"
},
"first_array" : [{ "_id" : "5b98987f08925c0f5cd86784", "floor" : "4th floor",
"second_array" : [ ]
}]
}
Basically what i was hoping to do is to let each of the array produces the total number of elements
in the array for second alongside with the main section so for example
design would output 3
training would output 5
forecast would output 0
internal audit would output 0
research would output 0
So, any help is greatly appreciated!
Related
this is the collection "Record" :
{
"_id" : "883f6174-fbbb-47f8-b280-7a798e8c0664",
"history" : [
{
"_id" : "6bdd2919-9fe5-48b8-a009-5dec0efc10c3",
"oldStatus" : "-NA-",
"newStatus" : "IN_PROGRESS",
"createdAt" : ISODate("2022-07-22T20:58:30.361Z")
},
{
"_id" : "eedb3775-93e2-4f0d-afda-0032b7b343dd",
"oldStatus" : "IN_PROGRESS",
"newStatus" : "ACCEPTED",
"createdAt" : ISODate("2022-10-10T16:30:04.781Z")
}
],
"source" : {
"$ref" : "Source",
"$id" : "65268f59-2a92-4414-8a79-c454c8059005"
},
"pipelineCreatedAt" : ISODate("2022-07-22T20:58:30.361Z")
}
I tried
{$addFields: {inProgressDate : {$cond:{if:{$and: [{ $eq: [ "$history.oldStatus", '-NA-' ] },{ $eq: [ "$history.newStatus", 'IN_PROGRESS' ] }]},then:"$history.createdAt",else:null}}}}
Expecting
My goal is :
WHERE progress time = oldStatus : "-NA-" and newStatus : "IN_PROGRESS"
and accepted time = oldStatus : "IN_PROGRESS" and newStatus : "ACCEPTED"
I was get an result of aggregate query from collection using $facet and $group aggregate but our development team does not satisfies with this result they are asked result must not be an objects given end
{
"_id" : ObjectId("6316e1b9a9ac1f9acceaf488"),
"status_counts" : [
{
"_id" : {
"status" : "Closed"
},
"count" : 59662.0
},
{
"_id" : {
"status" : "Open"
},
"count" : 695.0
},
{
"_id" : {
"status" : "Pending"
},
"count" : 4039.0
}
],
"Priority_counts" : [
{
"_id" : {
"Priority" : "Escalated"
},
"count" : 4722.0
},
{
"_id" : {
"Priority" : "Low"
},
"count" : 11.0
},
{
"_id" : {
"Priority" : "High"
},
"count" : 1.0
},
{
"_id" : {
"Priority" : "Medium"
},
"count" : 1.0
}
],
"assigned" : [
{
"_id" : true,
"count" : 4351.0
},
{
"_id" : false,
"count" : 383.0
}
],
"transfered" : [
{
"_id" : true,
"count" : 245.0
}
],
"cc" : [
{
"_id" : true,
"count" : 4.0
}
]
}
===================================================================================
From the above document expected output as below.. can anyone suggest me please..
{
"_id" : ObjectId("6316e1b9a9ac1f9acceaf488"),
"status_counts" : [
{
"status" : "Closed",
"count" : 59662.0
},
{
"status" : "Open"
"count" : 695.0
},
{
"status" : "Pending"
"count" : 4039.0
}
],
"Priority_counts" : [
{
"Priority" : "Escalated"
"count" : 4722.0
},
{
"Priority" : "Low"
"count" : 11.0
},
{
"Priority" : "High"
"count" : 1.0
},
{
"Priority" : "Medium"
"count" : 1.0
}
],
"assigned" : [
{
"_id" : true,
"count" : 4351.0
},
{
"_id" : false,
"count" : 383.0
}
],
"transfered" : [
{
"_id" : true,
"count" : 245.0
}
],
"cc" : [
{
"_id" : true,
"count" : 4.0
}
]
}
how can I query to get the specific message from either inbox or outbox given that I have its _id --> i.e. message id.
this is my route
get("/getSpecificMessage/{Message_id}", (req, res) => {..}
what I can do is find all the buyer/dealer and then go through inbox/outbox of all the buyer/dealer and then find the message with _id i.e. message_id
--> can I do it better then that.
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e1"),
"address" : {
"proper_address" : "sarai kale khan",
"lat" : 28.58894,
"long" : "77.25692"
},
"name" : "prashant",
"password" : "jfalksdjlk;jasdl",
"email" : "prashant#gmail.com",
"inbox" : [
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e4"),
"date" : ISODate("2018-09-04T23:03:41.627Z"),
"from" : "1#1.com",
"message" : "message_1"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e3"),
"date" : ISODate("2018-09-04T23:03:41.627Z"),
"from" : "2#2.com",
"message" : "message_2"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e2"),
"date" : ISODate("2018-09-04T23:03:41.627Z"),
"from" : "3#3.com",
"message" : "message_3"
}
],
"outbox" : [
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e7"),
"date" : ISODate("2018-09-04T23:03:41.627Z"),
"to" : "1#1.com",
"message" : "message_4"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e6"),
"date" : ISODate("2018-09-04T23:03:41.627Z"),
"to" : "1#1.com",
"message" : "message_5"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e5"),
"date" : ISODate("2018-09-04T23:03:41.627Z"),
"to" : "1#1.com",
"message" : "message_6"
}
],
"__v" : 0
}
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e8"),
"address" : {
"proper_address" : "najafgarah",
"lat" : 28.58894,
"long" : "77.25692"
},
"name" : "rahul",
"password" : "jkalsjdflasdl",
"email" : "rahul#gmail.com",
"inbox" : [
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083eb"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"from" : "1#1.com",
"message" : "message_1"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083ea"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"from" : "2#2.com",
"message" : "message_2"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e9"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"from" : "3#3.com",
"message" : "message_3"
}
],
"outbox" : [
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083ee"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"to" : "1#1.com",
"message" : "message_4"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083ed"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"to" : "1#1.com",
"message" : "message_5"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083ec"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"to" : "1#1.com",
"message" : "message_6"
}
],
"__v" : 0
}
So if I have the _id = 5b8f0f4de276dd1e0ff083ea and I want
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083ea"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"from" : "2#2.com",
"message" : "message_2"
}
I am not sure if you want it using MongoDB scripts or your app language (Nodejs if I am mistaken)
This is how it works on Mongo Shell Script
db.MODEL.find( { _id: DOCUMENT_ID },
{ inbox: { $elemMatch: { _id: MESSAGE_ID } } } )
Documentation is here
If this is not what you want, please update your post and add which language/framework you are using
This is what you could do using the aggregation framework:
var oId = new ObjectId("5b8f0f4de276dd1e0ff083ea");
db.collection.aggregate({
$match: { // can be skipped but I'd personally keep it because this will use an index on "input._id"/"output._id" (if there is one) to filter out irrelevant documents
$or: [
{ "inbox": { $elemMatch: { "_id": oId } } },
{ "outbox": { $elemMatch: { "_id": oId } } },
]
}
}, {
$project: {
result: {
$concatArrays: [
{ $filter: { "input": "$inbox", "cond": { $eq: [ "$$this._id", oId ] } } },
{ $filter: { "input": "$outbox", "cond": { $eq: [ "$$this._id", oId ] } } }
]
}
}
}, {
$unwind: "$result" // flatten the result array
}, {
$replaceRoot: {
"newRoot": "$result" // move "result" contents all the way up
}
})
I'm having some trouble with querying a Mongo Collection.
I have a Collection like this:
{
"_id" : "555bd34329de3cf232434ef2",
"cars" : [
{
"0" : {
"parts" : [
{
"name" : "x1",
"price" : 12
},
{
"name" : "x2",
"price" : 14
}
]
},
"1" : {
"parts" : [
{
"name" : "y1",
"price" : 8
},
{
"name" : "y2",
"price" : 12
}
]
}
}
]
}
I'd like to return just the following:
"parts" : [
{
"name" : "x1",
"price" : 12
},
{
"name" : "x2",
"price" : 14
}
]
In other words, I need to figure out how to query the Collection by two parameters at the same time:
where the ID matches "555bd34329de3cf232434ef2"
where the "name" of the part matches "x1"
Does anyone know how to do this kind of nested query?
Assuming a document structure like this:
{
"_id" : ObjectId("555bd34329de3cf232434ef2"),
"cars" : [
{
"parts" : [
{
"name" : "x1",
"price" : 12
},
{
"name" : "x2",
"price" : 14
}
]
},
{
"parts" : [
{
"name" : "y1",
"price" : 8
},
{
"name" : "y2",
"price" : 12
}
]
}
]
}
you can run the following query:
db.collection.find({ "_id": ObjectId("555bd34329de3cf232434ef2"), "cars.parts.name" : "x1" }, { "_id": 0, "cars.$": 1 })
which will get you pretty close to where you want to be:
{
"cars" : [
{
"parts" : [
{
"name" : "x1",
"price" : 12
},
{
"name" : "x2",
"price" : 14
}
]
}
]
}
You could get closer using the aggregation framework if that's not good enough...
I'm trying to remove data from a sub array as follow but am having difficulties.
{
"_id" : "0",
"mainArray" : [
{
"price" : 12,
"informations" : [
{
"createdBy" : "0x957a1a87d653ea2218742aeea5a05f637b6509c4",
"orderId" : 1
},
{
"createdBy" : "0x957a1a87d653ea2218742aeea5a05f637b6509c4",
"orderId" : 2
}
]
},{
"price" : 45,
"informations" : [
{
"createdBy" : "0x957a1a87d653ea2218742aeea5a05f637b6509c4",
"orderId" : 5
},
{
"createdBy" : "0x957a1a87d653ea2218742aeea5a05f637b6509c4",
"orderId" : 6
}
]
}
I would like the output to be :
{
"_id" : "0",
"mainArray" : [
{
"price" : 12,
"informations" : [
{
"createdBy" : "0x957a1a87d653ea2218742aeea5a05f637b6509c4",
"orderId" : 1
},
{
"createdBy" : "0x957a1a87d653ea2218742aeea5a05f637b6509c4",
"orderId" : 2
}
]
},{
"price" : 45,
"informations" : [
{
"createdBy" : "0x957a1a87d653ea2218742aeea5a05f637b6509c4",
"orderId" : 5
}
]
}
I've tried this :
db.collection.update({ "_id": "0" }, { $pull: { 'mainArray.informations': { "orderId": 6 } } });
and
db.collection.update({ "_id": "0" }, { $pull: { 'mainArray.0.informations': { "orderId": 6 } } });
But both don't work, the best i'm getting :
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
Anyone see where i'm going wrong ?
You need to use the positional operator '$' . $ is a positional operator which identifies an element in an array to update without explicitly specifying the position of the element in the array
db.collection.update({ "_id": "0" ,"mainArray.informations.orderId":6 },
{ $pull: { 'mainArray.$.informations': { "orderId": 6 } } });
Note : the array field must appear as part of the query document to figure out the matching position in mainArray.