问题
Running an aggregation such as the following:
[
{
"$match":{
"datasourceName":"Startup Failures",
"sheetName":"Data",
"Cost":{
"$exists":true
},
"Status":{
"$exists":true
}
}
},
{
"$group":{
"Count of Cost":{
"$sum":1
},
"Count of Status":{
"$sum":1
},
"_id":null
}
},
{
"$project":{
"Count of Cost":1,
"Count of Status":1
}
}
]
The result of the exists filters actually filters out the whole documents where "Cost" or "Status" do not exist. Such that the projection (Count) of both Cost and Status are the same. I don't want to filter the whole document only the individual columns such that the projection I get is the number of documents where Cost exists (Count of Cost) and the other projection is the number of documents where Status exists. In the case of my data these would give two separate numbers.
回答1:
I have an aggregation using $facet
; this allows do queries in parallel for each document pass. So, we query and count the Cost
and Status
as two facets of the same query.
db.test.aggregate( [
{
$match: { fld1: "Data" }
},
{
$facet: {
cost: [
{ $match: { cost: { $exists: true } } },
{ $count: "count" }
],
status: [
{ $match: { status: { $exists: true } } },
{ $count: "count" }
],
}
},
{
$project: {
costCount: { $arrayElemAt: [ "$cost.count" , 0 ] },
statusCount: { $arrayElemAt: [ "$status.count" , 0 ] }
}
}
] )
I get a result of { "costCount" : 4, "statusCount" : 3 }
, using the following documents:
{ _id: 1, fld1: "Data", cost: 12, status: "Y" },
{ _id: 2, fld1: "Data", status: "N" },
{ _id: 3, fld1: "Data" },
{ _id: 4, fld1: "Data", cost: 90 },
{ _id: 5, fld1: "Data", cost: 44 },
{ _id: 6, fld1: "Data", cost: 235, status: "N" },
{ _id: 9, fld1: "Stuff", cost: 0, status: "Y" }
NOTE: Here is a similar query using the facets: MongoDB Custom sorting on two fields.
来源:https://stackoverflow.com/questions/59158391/mongodb-exists-per-column