The collection I'm querying looks like this:
[
{
"_id": {"$oid": "5fa8408978d1511e9b6ecee9"},
"client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
"date_created": {"$date": "2020-11-08T19:01:29.460Z"},
"delivery_result_id": 0,
"lead_id": {"$oid": "5fa84082c9ac031d0c4b6c01"}
},
{
"_id": {"$oid": "5fa825495ee4001d2e0c2122"},
"client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
"date_created": {"$date": "2020-11-08T17:05:13.126Z"},
"delivery_result_id": 0,
"lead_id": {"$oid": "5fa82527c9ac031d0c4b6bfe"}
},
{
"_id": {"$oid": "5fa825495ee4001d2e0c2121"},
"client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
"date_created": {"$date": "2020-11-08T17:05:13.125Z"},
"delivery_result_id": 0,
"lead_id": {"$oid": "5fa8251fc9ac031d0c4b6bfb"}
},
{
"_id": {"$oid": "5fa825495ee4001d2e0c2120"},
"client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
"date_created": {"$date": "2020-11-08T17:05:13.125Z"},
"delivery_result_id": 100,
"lead_id": {"$oid": "5fa82516c9ac031d0c4b6bf8"}
},
{
"_id": {"$oid": "5fa823e08b542d1d1c91d30e"},
"client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
"date_created": {"$date": "2020-11-08T16:59:12.362Z"},
"delivery_result_id": 0,
"lead_id": {"$oid": "5fa823d9c9ac031d0c4b6bf5"}
},
{
"_id": {"$oid": "5fa823e08b542d1d1c91d30a"},
"client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
"date_created": {"$date": "2020-11-08T16:59:12.253Z"},
"delivery_result_id": 0,
"lead_id": {"$oid": "5fa823d3c9ac031d0c4b6bf2"}
},
{
"_id": {"$oid": "5fa823e08b542d1d1c91d300"},
"client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
"date_created": {"$date": "2020-11-08T16:59:12.125Z"},
"delivery_result_id": 100,
"lead_id": {"$oid": "5fa823c1c9ac031d0c4b6bef"}
},
{
"_id": {"$oid": "5fa823e08b542d1d1c91d2ff"},
"client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
"date_created": {"$date": "2020-11-08T16:59:12.125Z"},
"delivery_result_id": 100,
"lead_id": {"$oid": "5fa823bac9ac031d0c4b6bec"}
}
]
I'm trying to figure out how many documents in a row have delivery_result_id
of 0
starting from the latest document. My query has to include a cut off date beyond which I don't bother looking. But in the docs that came in after the date I need to could successive delivery_result_id
of 0
. Here is my aggregation:
db.lead_delivery_logs.aggregate([
{
$match: {
client_id: ObjectId('5f8d29a2beffbd2e00f81a54'),
date_created: {$gte: new Date("2020-11-07T16:59:12.362Z")}
}
},
{
$sort : {_id : -1}
},
{
$match: {
/* This is where I need to figure out that count */
}
},
])
Since I only need the count, ideally, the aggregation would return 3
from the collection above, because there are 3 docs that match delivery_result_id
of 0
and then comes one that's 100
so the count stops.
You can try,
$group
by null and prepare one array call root
of all documents$reduce
to iterate loop of root
array and set initial value result array and status default 0, check condition if delivery_result_id
is 0 and initial value is true
, then concat object with initial value result
otherwise set status false
$unwind
deconstruct result array$replaceRoot
replace to root result objectdb.collection.aggregate([
{
$match: {
client_id: ObjectId("5f8d29a2beffbd2e00f81a54"),
date_created: { $gte: new Date("2020-11-07T16:59:12.362Z") }
}
},
{ $sort: { _id: -1 } },
{
$group: {
_id: null,
root: { $push: "$$ROOT" }
}
},
{
$project: {
root: {
$reduce: {
input: "$root",
initialValue: { result: [], status: true },
in: {
$cond: [
{
$and: [
{ $eq: ["$$this.delivery_result_id", 0] },
{ $eq: ["$$value.status", true] }
]
},
{
result: { $concatArrays: ["$$value.result", ["$$this"]] },
status: true
},
{
result: "$$value.result",
status: false
}
]
}
}
}
}
},
{ $unwind: "$root.result" },
{ $replaceRoot: { newRoot: "$root.result" } }
])
Very clever indeed. I certainly didn't expect it to be this elaborate. If you had the choice of doing it this way OR returning all the matching documents from the first 2 conditions of the pipeline back into your app and doing this calculation inside your app (using JS or whatever language), would you still do it inside an aggregation? Seems like a lot of work for Mongo.
of course i will do it in my language client side, we can save 4 stages of processing from mongo and client side language would do that in less time.
Make sense. Little doubt that your post answers my question though. Thank you.