mongodb - 如何根据条件选择进行查找?
问题描述
我有 2 个基于 collection1 的集合,我需要从 collection2 中获取
集合1
[
{
"_id": ObjectId("5ce7454f77af2d1143f84c38"),
"menu_name": "mainmenu1",
"sub_menus": [
{
"name": "submenu1",
"project": [
"All"
]
},
{
"name": "submenu2",
"project": [
"p2"
]
}
]
}
]
根据项目字段,我需要获取记录。如果项目字段是“全部”,我需要获取该子菜单下的所有项目。如果它是特定项目,则只有我需要获取的那些项目。
这是我的收藏2
集合2
"project": [
{
"project_name": "p1",
"sub_menus": "submenu1",
},
{
"project_name": "p2",
"sub_menus": "submenu2",
}
{
"project_name": "p2",
"sub_menus": "submenu1",
},
{
"project_name": "p3",
"sub_menus": "submenu2",
}
{
"project_name": "p3",
"sub_menus": "submenu1",
},
{
"project_name": "p4",
"sub_menus": "submenu2",
}
]
https://mongoplayground.net/p/qH9fuJorq6z。我可以进行条件查找吗?
预期结果是
[
{
"_id": ObjectId("5ce7454f77af2d1143f84c38"),
"menu_name": "mainmenu1",
"sub_menus": [
{
"projectData": [
{
"project_name": "p1"
},
{
"project_name": "p2"
},
{
"project_name": "p3"
}
],
"sub_menu_name": "submenu1"
},
{
"projectData": [
{
"project_name": "p2"
}
],
"sub_menu_name": "submenu2"
}
]
}
]
解决方案
是的,您可以为$ lookup 管道定义您自己的匹配条件,但是由于您的结构是深度嵌套的,您需要在运行. 将所有匹配到任何子菜单的项目带入后,您可以使用 $map 和 $filter 将它们放入 releval :sub_menus
$lookup
sub_menu
db.collection1.aggregate([
{
$addFields: {
sub_menus_flat: {
$reduce: {
input: "$sub_menus",
initialValue: [],
in: {
$concatArrays: [
"$$value",
{ $map: { input: "$$this.project", as: "p", in: { name: "$$this.name", project: "$$p" } } }
]
}
}
}
}
},
{
$lookup: {
from: "collection2",
let: { sub_menus_flat: "$sub_menus_flat" },
pipeline: [
{
$match: {
$expr: {
$anyElementTrue: {
$map: {
input: "$$sub_menus_flat",
in: {
$and: [
{ $eq: [ "$$this.name", "$sub_menus" ] },
{ $in: [ "$$this.project", [ "All", "$project_name" ] ] }
]
}
}
}
}
}
}
],
as: "projects"
}
},
{
$project: {
_id: 1,
menu_name: 1,
sub_menus: {
$map: {
input: "$sub_menus",
in: {
sub_menu_name: "$$this.name",
projectData: {
$filter: {
input: "$projects",
as: "p",
cond: {
$and: [
{ $eq: [ "$$p.sub_menus", "$$this.name" ] }
]
}
}
}
}
}
}
}
},
{
$project: {
"sub_menus.projectData._id": 0,
"sub_menus.projectData.sub_menus": 0
}
}
])
推荐阅读
- html - ERROR 错误:找不到带有路径的控件:'stocks -> stockName'
- sql - 在 Big Query 中制作连接表数组的最佳方法是什么?
- c# - 使用 EF Core 配置 Serilog ASP.Net Core 3.2 以记录 SQL 语句
- javascript - 导入时更改角度库的主题
- node.js - Mongoose 与 MongoDB 模式验证器
- java - Java android API 30 不在 ACTION_VIEW 中显示照片
- c++ - 访问 2d Apollonius 图 CGAL-加权 Voronoi 图的面和顶点
- netty - Netty 服务器无法获取客户端发送的所有消息
- javascript - 为什么 data-html="true" 不能使用工具提示?
- cassandra - Cassandra - SyntaxException: line ... 在 select 语句的输入中没有可行的替代方案