MongoDb : 从嵌套映射中查找和过滤值
MongoDb : Find and filter values from nested map
我在 mongo db
有约会
[
{
"_id": ObjectId("5a934e000102030405000000"),
"orgId": "606abce197dc265ac41ae82c",
"registrations": {
"id1": {
"status": "status",
"topStage": {
"id": "stage1",
"name": "stage1"
}
},
"id2": {
"status": "status",
"topStage": {
"id": "stage1",
"name": "stage1"
}
},
"id3": {
"status": "status",
"topStage": {
"id": "stage2",
"name": "stage2"
}
}
}
}
]
我希望传递阶段 ID(在路径注册-> topStage -> id)和 return 所有匹配的键值。
我写了以下查询
db.collection.aggregate([
{
$project: {
teams: {
$objectToArray: "$registrations"
},
original: "$$ROOT"
}
},
{
"$project": {
"teams": {
"$filter": {
"input": "$teams",
"as": "team",
"cond": {
"$eq": [
"$$team.v.topStage.id",
"stage1"
]
}
}
}
}
},
{
"$project": {
"registrations": {
"$arrayToObject": "$teams"
}
}
}
])
它确实 return 我正确的价值观
对于 stage1 作为阶段 id
[
{
"_id": ObjectId("5a934e000102030405000000"),
"registrations": {
"id1": {
"status": "status",
"topStage": {
"id": "stage1",
"name": "stage1"
}
},
"id2": {
"status": "status",
"topStage": {
"id": "stage1",
"name": "stage1"
}
}
}
}
]
对于阶段 2 作为阶段 ID,它 returns
[
{
"_id": ObjectId("5a934e000102030405000000"),
"registrations": {
"id3": {
"status": "status",
"topStage": {
"id": "stage2",
"name": "stage2"
}
}
}
}
]
有人可以告诉我这是编写此查询的最佳方式还是可以简化这种方式??
这是正确的做法,但在以下情况下会影响性能。
- 如果您没有任何其他与索引匹配的条件
- 如果您有一个匹配条件,并且它匹配了几个注册有更多对象的文档
您可以做的其他最佳选择是更改架构。
- 您可以将 registrations.id1 保留为
registrations : { id:1, status_id: 2}
- 或者你可以改变方式,这样它就不需要在更大的集合上使用 objectToArray
- 如果您的数据量很大,我建议在嵌套状态 Id 字段上添加索引。
并且 mongo 文档本身建议评估任何数据的多个模式以充分利用它。
我在 mongo db
有约会[
{
"_id": ObjectId("5a934e000102030405000000"),
"orgId": "606abce197dc265ac41ae82c",
"registrations": {
"id1": {
"status": "status",
"topStage": {
"id": "stage1",
"name": "stage1"
}
},
"id2": {
"status": "status",
"topStage": {
"id": "stage1",
"name": "stage1"
}
},
"id3": {
"status": "status",
"topStage": {
"id": "stage2",
"name": "stage2"
}
}
}
}
]
我希望传递阶段 ID(在路径注册-> topStage -> id)和 return 所有匹配的键值。
我写了以下查询
db.collection.aggregate([
{
$project: {
teams: {
$objectToArray: "$registrations"
},
original: "$$ROOT"
}
},
{
"$project": {
"teams": {
"$filter": {
"input": "$teams",
"as": "team",
"cond": {
"$eq": [
"$$team.v.topStage.id",
"stage1"
]
}
}
}
}
},
{
"$project": {
"registrations": {
"$arrayToObject": "$teams"
}
}
}
])
它确实 return 我正确的价值观 对于 stage1 作为阶段 id
[
{
"_id": ObjectId("5a934e000102030405000000"),
"registrations": {
"id1": {
"status": "status",
"topStage": {
"id": "stage1",
"name": "stage1"
}
},
"id2": {
"status": "status",
"topStage": {
"id": "stage1",
"name": "stage1"
}
}
}
}
]
对于阶段 2 作为阶段 ID,它 returns
[
{
"_id": ObjectId("5a934e000102030405000000"),
"registrations": {
"id3": {
"status": "status",
"topStage": {
"id": "stage2",
"name": "stage2"
}
}
}
}
]
有人可以告诉我这是编写此查询的最佳方式还是可以简化这种方式??
这是正确的做法,但在以下情况下会影响性能。
- 如果您没有任何其他与索引匹配的条件
- 如果您有一个匹配条件,并且它匹配了几个注册有更多对象的文档
您可以做的其他最佳选择是更改架构。
- 您可以将 registrations.id1 保留为
registrations : { id:1, status_id: 2}
- 或者你可以改变方式,这样它就不需要在更大的集合上使用 objectToArray
- 如果您的数据量很大,我建议在嵌套状态 Id 字段上添加索引。
并且 mongo 文档本身建议评估任何数据的多个模式以充分利用它。