not able to query through an array in mongodb aggregation - arrays

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"

Related

How can I specific array values as out as given below?

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 to make new array from another array during aggregation?

I have following document:
{
"subscriptionIds" : [
ObjectId("60c312c6dbb5a49fbbf560ea")
],
"gps" : {
"type" : "Point",
"coordinates" : [
23.942706,
54.932539
]
},
"online" : false,
"suspended" : false,
"hwModel" : "",
"fw" : "",
"lastSeen" : ISODate("2021-06-16T04:43:36.682Z"),
"lastSimRequest" : ISODate("2021-06-16T04:34:59.749Z"),
"lastLocation" : "LT",
"lastLocationType" : "gps",
"createdAt" : ISODate("2021-05-20T10:37:16.025Z"),
"updatedAt" : ISODate("2021-06-11T07:37:56.981Z"),
"notes" : "",
"psk_seed" : "QTAebOeNP4nIs-JJSNNlkAQ78N_VaxOq98-_lQPCyZQ=",
"lastOnline" : ISODate("2021-06-15T08:01:59.886Z"),
"lastOffline" : ISODate("2021-06-16T04:43:36.682Z"),
"onlineReason" : "deviceOnlineStatusFromAC",
"offlineReason" : "deviceOfflineStatusTimeout",
"allocationSettings" : "dataplan",
"subscriptionDataplans" : [
{
"_id" : ObjectId("5fae82fc1224cc8d62b5bf17"),
"organizationId" : ObjectId("5dd63d1c1d042f3018e8374e"),
"organizationName" : "",
"name" : "Naujas plan Telia 75GB",
"enabled" : true,
"contractsId" : [
ObjectId("5e32847ab8013befcc14bb1b"),
ObjectId("5e32847ab8013befcc14bb1b")
],
"simQuota" : 0,
"periodQuota" : NumberLong(0),
"allocationRules" : null,
"createdAt" : ISODate("2020-11-13T12:58:36.650Z"),
"updatedAt" : ISODate("2021-06-14T08:08:28.728Z"),
"notes" : "",
"allowRoaming" : false,
"enablePriorityOrdering" : false,
"priorityOrdering" : ""
},
{
"_id" : ObjectId("5fcf25662b1c7d9bab8c1f7d"),
"organizationId" : ObjectId("5dd63d1c1d042f3018e8374e"),
"organizationName" : "",
"name" : "London test",
"enabled" : true,
"contractsId" : [
ObjectId("5e5dfea1efcf754767408eae")
],
"simQuota" : 0,
"periodQuota" : NumberLong(0),
"createdAt" : ISODate("2020-12-08T07:04:06.255Z"),
"updatedAt" : ISODate("2021-06-15T09:28:07.472Z"),
"notes" : "",
"allowRoaming" : true,
"enablePriorityOrdering" : false,
"priorityOrdering" : ""
}
],
}
Is there a way to make following array using "_id" and "allowRoaming" fields:
"dataplanRoaming": [
{
"_id" : ObjectId("5fae82fc1224cc8d62b5bf17"),
"allowRoaming" : false,
},
{
"_id" : ObjectId("5fcf25662b1c7d9bab8c1f7d"),
"allowRoaming" : true,
}
]
My best result was, I tried using project, addFields etc still can't get structure which I want. Rest of query works just fine just missing this part
"dataplanRoaming" : [
[
false,
true
],
[
ObjectId("5fae82fc1224cc8d62b5bf17"),
ObjectId("5fcf25662b1c7d9bab8c1f7d")
]
],
I hoped that {$addFields:{dataplanRoaming:["$subscriptionDataplans.allowRoaming", "$subscriptionDataplans._id"]}},
would give me wanted result it just made array with _id and allowRoaming as separates fields?
Is there a way to create my wanted result using aggregation etc?
$map to iterate loop of subscriptionDataplans and return needed feidls
db.collection.aggregate([
{
$addFields: {
dataplanRoaming: {
$map: {
input: "$subscriptionDataplans",
in: {
_id: "$$this._id",
allowRoaming: "$$this.allowRoaming"
}
}
}
}
}
])
Playground

count inner array mongoose

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!

mongo query - getting a specific object (its `_id` is known) from array of object BUT this array is also a part of list of documents

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
}
})

MongoDB query with elemMatch for nested array data and return only matching elements

{
"_id" : NumberLong(107),
"cnic" : NumberLong(098765),
"recordsOFGt" : [
{
"records" : [
{
"_id" : NumberLong(1),
"contactIds" : [
NumberLong(303)
],
},
{
"_id" : NumberLong(2),
"contactIds" : [
NumberLong(303),
NumberLong(304)
],
},
{
"_id" : NumberLong(3),
"contactIds" : [
NumberLong(309),
NumberLong(304)
],
},
{
"_id" : NumberLong(4),
"contactIds" : [
NumberLong(303),
NumberLong(304)
],
},
{
"_id" : NumberLong(5),
"contactIds" : [
NumberLong(303),
NumberLong(304)
],
},
]
},
"records2" : {
...
...
}
]
}
I want only record element that will be matched via _id I have tried this
db.getCollection('tempCollection').findOne(
{ 'recordsOFGt': {$elemMatch: {'records._id': 1} }},
{'recordsOFGt.$': 1}
)
this returns all elements of records array need just matching element.
this is what I want as output :
{
"records" :
{
"_id" : NumberLong(1),
"contactIds" : [
NumberLong(303)
],
}
}

Resources