问题
I'm trying to match two different fields in the same document. But didn't get expected output as I want. Let me show with an example.
I want to match weighted.phaseId
with phases._id
in same documents and not match should be removed from phases
fields.
Does any one have an Idea ?
// Document after processing some aggregate query over a database.
{
"_id" : ObjectId("5a680c803096130f93d11c7a"),
"weighted" : [
{
"phaseId" : ObjectId("5a6734c32414e15d0c2920f0"),
"_id" : ObjectId("5a680c803096130f93d11c7b")
},
{
"phaseId" : ObjectId("5a6734c32414e15d0c2920ee"),
"_id" : ObjectId("5a680c803096130f93d11c7c")
}
],
"phases" : [
{
"phase_name" : "Phase 1",
"_id" : ObjectId("5a6734c32414e15d0c2920f0")
},
{
"phase_name" : "Phase 2",
"_id" : ObjectId("5a6734c32414e15d0c2920ef")
},
{
"phase_name" : "Phase 3",
"_id" : ObjectId("5a6734c32414e15d0c2920ee")
},
{
"phase_name" : "Phase 4",
"_id" : ObjectId("5a6734c32414e15d0c2920ed")
}
]
}
// Expected Output
{
"_id" : ObjectId("5a680c803096130f93d11c7a"),
"weighted" : [
{
"phaseId" : ObjectId("5a6734c32414e15d0c2920f0"),
"_id" : ObjectId("5a680c803096130f93d11c7b")
},
{
"phaseId" : ObjectId("5a6734c32414e15d0c2920ee"),
"_id" : ObjectId("5a680c803096130f93d11c7c")
}
],
"phases" : [
{
"phase_name" : "Phase 1",
"_id" : ObjectId("5a6734c32414e15d0c2920f0")
},
{
"phase_name" : "Phase 3",
"_id" : ObjectId("5a6734c32414e15d0c2920ee")
}
]
}
回答1:
You can use following aggregation:
db.col.aggregate([
{
$addFields: {
weightedIds: {
$map:
{
input: "$weighted",
as: "w",
in: "$$w.phaseId"
}
}
}
},
{
$project: {
_id: 1,
weighted: 1,
phases: {
$filter: {
input: "$phases",
as: "phase",
cond: { $gte: [ { $indexOfArray: [ "$weightedIds" , "$$phase._id" ] }, 0 ] }
}
}
}
}
])
We're using $map
to take only phaseId
field of weighted
and then we can filter out phases
using $filter checking for each phase whether corresponding id
exists (using $indexOfArray which returns -1 otherwise)
来源:https://stackoverflow.com/questions/48556504/match-two-different-fields-in-mongoose-aggregate