使用投影过滤嵌套数组而不使用展开
Filter nested array using projection without using unwind
我有我的 collection1,它在项目字段中包含 collection2 的 _id,如下所示:
{
"name": "adafd",
"employeeId": "employeeId",
"locations": [
"ObjectId(adfaldjf)",
"ObjectId(adfaldjf)",
"ObjectId(adfaldjf)",
"ObjectId(adfaldjf)",
"ObjectId(adfaldjf)",
"ObjectId(adfaldjf)"
]
}
合集2如下
"collection2": [
{
"location": "india",
"states": [
{
"stateCode": "TN",
"districts": {
"cities": [
{
"code": 1,
"name": "xxx"
},
{
"code": 4,
"name": "zzz"
},
{
"code": 6,
"name": "yyy"
}
]
}
}
]
}
]
我正在尝试在查找后过滤 collection2 中的嵌套数组,如下所示:
db.collection.aggregate([
{
$lookup: {
from: "collection2",
localField: "locations",
foreignField: "_id",
as: "locations"
}
},
{
$match: {
"name": "adafd",
},
},
{
$project: {
'details': {
$filter: {
input: "$locations",
as: "location",
cond: {
"$eq": ["$$location.states.stateCode", "TN" ]
}
}
}
}
}
]
)
它为 locations
返回一个空数组。
我按如下方式修改了项目,以在投影中甚至过滤 collection2 数组内的状态,但过滤器未应用。它返回 states
数组中的所有数据。
{
$project: {
'details': {
$filter: {
input: "$locations",
as: "location",
cond: {
$filter: {
input: "$location.states",
as: "state",
cond: {
"$eq": ["$$state.stateCode", "TN" ]
}
}
}
}
}
}
}
我已经找到了几个解决方案,但 none 对我有用。因为我不想使用放松。有什么办法可以做到这一点..?
注意:我不想在 $lookup 中使用 pipeline,因为 DocumentDB 不支持它。并且查询中还应该有 $unwind 和 $group。
您可能会使用 $map
。您的代码中有几个错误。 $match
需要 "locations.location":"india"
并且在 filter input
中你需要使用 $$<var name>
db.collection1.aggregate([
{
$lookup: {
from: "collection2",
localField: "locations",
foreignField: "_id",
as: "locations"
}
},
{
$project: {
"details": {
input: {
$map: {
input: "$locations",
as: "location",
in: {
"_id": "$$location._id",
location: "$$location.location",
states: {
$filter: {
input: "$$location.states",
as: "state",
cond: {
"$eq": [
"$$state.stateCode",
"TN"
]
}
}
}
}
}
}
}
}
}
])
假设如果你需要消除空状态的文件,你可以很容易地用match
你可以这样试试 有效
db.getCollection('col').aggregate([
{
$lookup: {
from: "col",
localField: "locations",
foreignField: "_id",
as: "locations"
}
},
{
$project: {
'locations': {
$filter: {
input: "$collection2",
as: "collection",
cond: {
"$eq": ["$$collection.location", "india" ],
}
}
}
}
},
{
$project: {
'details': {
$filter: {
input: "$locations",
as: "location",
cond: {
$filter: {
input: "$$location.states",
as: "state",
cond: {
"$eq": ["$$state.stateCode", "TN" ]
}
}
}
}
}
}
}
])
$match
你的条件
$lookup
与 collection2
$project
按位置名称过滤 locations
$unwind
解构locations
数组
$project
按州代码 过滤 states
$unwind
解构states
数组
$project
按城市代码 过滤 cities
$unwind
解构cities
数组
db.collection1.aggregate([
{ $match: { name: "adafd" } },
{
$lookup: {
from: "collection2",
localField: "locations",
foreignField: "_id",
as: "locations"
}
},
{
$project: {
locations: {
$filter: {
input: "$locations",
cond: { $eq: ["$$this.location", "india"] }
}
}
}
},
{ $unwind: "$locations" },
{
$project: {
locations: {
_id: "$locations._id",
location: "$locations.location",
states: {
$filter: {
input: "$locations.states",
cond: { $eq: ["$$this.stateCode", "TN"] }
}
}
}
}
},
{ $unwind: "$locations.states" },
{
$project: {
locations: {
_id: "$locations._id",
location: "$locations.location",
states: {
stateCode: "$locations.states.stateCode",
districts: {
cities: {
$filter: {
input: "$locations.states.districts.cities",
cond: { $eq: ["$$this.code", 1] }
}
}
}
}
}
}
},
{ $unwind: "$locations.states.districts.cities" }
])
不使用 $unwind
的第二个选项,而不是您可以使用 $arrayElemAt
、
db.collection1.aggregate([
{ $match: { name: "adafd" } },
{
$lookup: {
from: "collection2",
localField: "locations",
foreignField: "_id",
as: "locations"
}
},
{
$project: {
locations: {
$arrayElemAt: [
{
$filter: {
input: "$locations",
cond: { $eq: ["$$this.location", "india"] }
}
},
0
]
}
}
},
{
$project: {
locations: {
_id: "$locations._id",
location: "$locations.location",
states: {
$arrayElemAt: [
{
$filter: {
input: "$locations.states",
cond: { $eq: ["$$this.stateCode", "TN"] }
}
},
0
]
}
}
}
},
{
$project: {
locations: {
_id: "$locations._id",
location: "$locations.location",
states: {
stateCode: "$locations.states.stateCode",
districts: {
cities: {
$arrayElemAt: [
{
$filter: {
input: "$locations.states.districts.cities",
cond: { $eq: ["$$this.code", 1] }
}
},
0
]
}
}
}
}
}
}
])
我有我的 collection1,它在项目字段中包含 collection2 的 _id,如下所示:
{
"name": "adafd",
"employeeId": "employeeId",
"locations": [
"ObjectId(adfaldjf)",
"ObjectId(adfaldjf)",
"ObjectId(adfaldjf)",
"ObjectId(adfaldjf)",
"ObjectId(adfaldjf)",
"ObjectId(adfaldjf)"
]
}
合集2如下
"collection2": [
{
"location": "india",
"states": [
{
"stateCode": "TN",
"districts": {
"cities": [
{
"code": 1,
"name": "xxx"
},
{
"code": 4,
"name": "zzz"
},
{
"code": 6,
"name": "yyy"
}
]
}
}
]
}
]
我正在尝试在查找后过滤 collection2 中的嵌套数组,如下所示:
db.collection.aggregate([
{
$lookup: {
from: "collection2",
localField: "locations",
foreignField: "_id",
as: "locations"
}
},
{
$match: {
"name": "adafd",
},
},
{
$project: {
'details': {
$filter: {
input: "$locations",
as: "location",
cond: {
"$eq": ["$$location.states.stateCode", "TN" ]
}
}
}
}
}
]
)
它为 locations
返回一个空数组。
我按如下方式修改了项目,以在投影中甚至过滤 collection2 数组内的状态,但过滤器未应用。它返回 states
数组中的所有数据。
{
$project: {
'details': {
$filter: {
input: "$locations",
as: "location",
cond: {
$filter: {
input: "$location.states",
as: "state",
cond: {
"$eq": ["$$state.stateCode", "TN" ]
}
}
}
}
}
}
}
我已经找到了几个解决方案,但 none 对我有用。因为我不想使用放松。有什么办法可以做到这一点..?
注意:我不想在 $lookup 中使用 pipeline,因为 DocumentDB 不支持它。并且查询中还应该有 $unwind 和 $group。
您可能会使用 $map
。您的代码中有几个错误。 $match
需要 "locations.location":"india"
并且在 filter input
中你需要使用 $$<var name>
db.collection1.aggregate([
{
$lookup: {
from: "collection2",
localField: "locations",
foreignField: "_id",
as: "locations"
}
},
{
$project: {
"details": {
input: {
$map: {
input: "$locations",
as: "location",
in: {
"_id": "$$location._id",
location: "$$location.location",
states: {
$filter: {
input: "$$location.states",
as: "state",
cond: {
"$eq": [
"$$state.stateCode",
"TN"
]
}
}
}
}
}
}
}
}
}
])
假设如果你需要消除空状态的文件,你可以很容易地用match
你可以这样试试 有效
db.getCollection('col').aggregate([
{
$lookup: {
from: "col",
localField: "locations",
foreignField: "_id",
as: "locations"
}
},
{
$project: {
'locations': {
$filter: {
input: "$collection2",
as: "collection",
cond: {
"$eq": ["$$collection.location", "india" ],
}
}
}
}
},
{
$project: {
'details': {
$filter: {
input: "$locations",
as: "location",
cond: {
$filter: {
input: "$$location.states",
as: "state",
cond: {
"$eq": ["$$state.stateCode", "TN" ]
}
}
}
}
}
}
}
])
$match
你的条件$lookup
与 collection2$project
按位置名称过滤locations
$unwind
解构locations
数组$project
按州代码 过滤 $unwind
解构states
数组$project
按城市代码 过滤 $unwind
解构cities
数组
states
cities
db.collection1.aggregate([
{ $match: { name: "adafd" } },
{
$lookup: {
from: "collection2",
localField: "locations",
foreignField: "_id",
as: "locations"
}
},
{
$project: {
locations: {
$filter: {
input: "$locations",
cond: { $eq: ["$$this.location", "india"] }
}
}
}
},
{ $unwind: "$locations" },
{
$project: {
locations: {
_id: "$locations._id",
location: "$locations.location",
states: {
$filter: {
input: "$locations.states",
cond: { $eq: ["$$this.stateCode", "TN"] }
}
}
}
}
},
{ $unwind: "$locations.states" },
{
$project: {
locations: {
_id: "$locations._id",
location: "$locations.location",
states: {
stateCode: "$locations.states.stateCode",
districts: {
cities: {
$filter: {
input: "$locations.states.districts.cities",
cond: { $eq: ["$$this.code", 1] }
}
}
}
}
}
}
},
{ $unwind: "$locations.states.districts.cities" }
])
不使用 $unwind
的第二个选项,而不是您可以使用 $arrayElemAt
、
db.collection1.aggregate([
{ $match: { name: "adafd" } },
{
$lookup: {
from: "collection2",
localField: "locations",
foreignField: "_id",
as: "locations"
}
},
{
$project: {
locations: {
$arrayElemAt: [
{
$filter: {
input: "$locations",
cond: { $eq: ["$$this.location", "india"] }
}
},
0
]
}
}
},
{
$project: {
locations: {
_id: "$locations._id",
location: "$locations.location",
states: {
$arrayElemAt: [
{
$filter: {
input: "$locations.states",
cond: { $eq: ["$$this.stateCode", "TN"] }
}
},
0
]
}
}
}
},
{
$project: {
locations: {
_id: "$locations._id",
location: "$locations.location",
states: {
stateCode: "$locations.states.stateCode",
districts: {
cities: {
$arrayElemAt: [
{
$filter: {
input: "$locations.states.districts.cities",
cond: { $eq: ["$$this.code", 1] }
}
},
0
]
}
}
}
}
}
}
])