C# Mongodb 多个对象数组文档的笛卡尔积

2024-03-01

尝试使用 C#/Linq 甚至原始 Mongodb 查询本身来了解如何将多个数组连接为笛卡尔积。

举例来说,我有一个集合,我将其过滤为以下两个文档:

[
{"movie":"starwars","showday":"monday"},
{"movie":"batman","showday":"thursday"},
{"movie":"sleepless","showday":"tuesday"}
]

[
{"actor":"angelina","location":"new york"},
{"actor":"jamie","location":"california"},
{"actor":"mcavoy","location":"arizona"}
]

如何连接每个数组中的每个项目以产生以下类型的结果?

[{"movie":"starwars","showday":"monday","actor":"angelina","location":"new york"},
{"movie":"batman","showday":"thursday","actor":"angelina","location":"new york"},
{"movie":"sleepless","showday":"tuesday","actor":"angelina","location":"new york"},
{"movie":"starwars","showday":"monday","actor":"jamie","location":"california"},
{"movie":"batman","showday":"thursday","actor":"jamie","location":"california"},
{"movie":"sleepless","showday":"tuesday","actor":"jamie","location":"california"},
{"movie":"starwars","showday":"monday","actor":"mcavoy","location":"arizona"},
{"movie":"batman","showday":"thursday","actor":"mcavoy","location":"arizona"},
{"movie":"sleepless","showday":"tuesday","actor":"mcavoy","location":"arizona"}]

我正在寻找一种可以处理任意数量文档的解决方案。例如,如果在此示例中存在第三个文档,该文档也包含 3 个对象数组,则该数组将生成数组中包含 27 个项目的结果集,或者说 27 行。

希望找到一个如何使用 C#(Linq?)Mongodb 驱动程序来查询和返回这样的数据的解决方案,但甚至可以对 mongodb 特定查询开放,因为我希望可以从那里反转逻辑。谢谢


您可以尝试下面的聚合管道。

Note 合并对象 https://jira.mongodb.org/browse/SERVER-24879聚合运算符可用于3.5.6 +开发版本将被纳入即将推出的3.6发布。

db.collection.find();
{
 "data" : [
  [
   {
    "movie" : "starwars",
    "showday" : "monday"
   },
   {
    "movie" : "batman",
    "showday" : "thursday"
   },
   {
    "movie" : "sleepless",
    "showday" : "tuesday"
   }
  ],
  [
   {
    "actor" : "angelina",
    "location" : "new york"
   },
   {
    "actor" : "jamie",
    "location" : "california"
   },
   {
    "actor" : "mcavoy",
    "location" : "arizona"
   }
  ]
 ]
}

使用条件表达式进行聚合。

aggregate({
 $project: {
  cp: {
   $reduce: {
    input: "$data",
    initialValue: {
     $arrayElemAt: ["$data", 0] // Set the initial value to the first element of the arrays.
    },
    in: {
     $let: {
      vars: {
       currentr: "$$this", // Current processing element
       currenta: "$$value" // Current accumulated value 
      },
      in: {
       $cond: [{ // Conditional expression to return the accumulated value as initial value for first element
        $eq: ["$$currentr", "$$currenta"]
       },
       "$$currenta",
       { // From second element onwards prepare the cartesian product
        $reduce: {
         input: {
          $map: {
           input: "$$currenta",
           as: a"a",
           in: {
            $map: {
             input: "$$currentr",
             as: r"r",
             in: {
              $mergeObjects: ["$$a", "$$r"] // Merge accumulated value with the current processing element
             }
            }
           }
          }
         },
         initialValue: [],
         in: {
         $concatArrays: ["$$value", "$$this"] // Reduce the merged values which will be used as accumulator for next element
         }
        }
       }]
      }
     }
    }
   }
  }
 }
});

聚合(使用$setUnion ).

添加此解决方案只是为了抑制条件表达式,以提供更具可读性的管道。

aggregate({
 $project: {
  cp: {
   $reduce: {
    input: "$data",
    initialValue: {
     $arrayElemAt: ["$data", 0] // Set the initial value to the first element of the arrays.
    },
    in: {
     $let: {
      vars: {
       currentr: "$$this", // Current processing element
       currenta: "$$value" // Current accumulated value 
      },
      in:{ 
       $reduce: {
        input: {
         $map: {
          input: "$$currenta",
          as: "a",
          in: {
           $map: {
            input: "$$currentr",
            as: "r",
            in: {
             $mergeObjects: ["$$a", "$$r"] // Merge accumulated value with the current processing element
            }
           }
          }
         }
        },
        initialValue: [],
        in: {
         $setUnion: ["$$value", "$$this"] // Reduce the merged values which will be used as accumulator for next element
        }
       }
      }
     }
    }
   }
  }
 }
});

Update

正如下面 Asya Kamsky 的评论所述,上述两种解决方案都不适用于跨数组的重复值,因为不正确$cond在第一个解决方案中和$setUnion在第二个解决方案中。

正确的解决方法是

从...开始initialValue of [ { } ]

Or

change input排除第一个元素,例如input: {$slice:["$data", 1, {$subtract:[{$size:"$data"},1]}]},

完整的聚合管道

aggregate({
 $project: {
  cp: {
   $reduce: {
    input: {$slice:["$data", 1, {$subtract:[{$size:"$data"},1]}]},
    initialValue: {$arrayElemAt:["$data",0]},
    in: {
     $let: {
      vars: {
       currentr: "$$this", 
       currenta: "$$value" 
      },
      in:{ 
       $reduce: {
        input: {
         $map: {
          input: "$$currenta",
          as: "a",
          in: {
           $map: {
            input: "$$currentr",
            as: "r",
            in: {
             $mergeObjects: ["$$a", "$$r"] 
            }
           }
          }
         }
        },
        initialValue: [],
        in: {
         $concatArrays: ["$$value", "$$this"] 
        }
       }
      }
     }
    }
   }
  }
 }
});

参考:JavaScript 中多个数组的笛卡尔积 https://stackoverflow.com/questions/12303989/cartesian-product-of-multiple-arrays-in-javascript

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# Mongodb 多个对象数组文档的笛卡尔积 的相关文章

  • 为什么 C 程序使用 Scanf 给出奇怪的输出?

    我目前正在学习 C 编程 并且遇到了这个奇怪的输出 Program will try functionalities of the scanf function include
  • 无法继承形状

    为什么我不能使用继承 a 的类Shapes class http msdn microsoft com en us library ms604615 28v vs 90 29 我需要延长Rectangle具有一些方法的类 但我想以与使用相同
  • 在 C++ 代码中转换字符串

    我正在学习 C 并开发一个项目来练习 但现在我想在代码中转换一个变量 字符串 就像这样 用户有一个包含 C 代码的文件 但我希望我的程序读取该文件并插入将其写入代码中 如下所示 include
  • Boost ASIO 串行写入十六进制值

    我正在使用 ubuntu 通过串行端口与设备进行通信 所有消息都必须是十六进制值 我已经在 Windows 环境中使用白蚁测试了通信设置 并得到了我期望的响应 但在使用 Boost asio 时我无法得到任何响应 以下是我设置串口的方法 b
  • 如何从另一个数组值中过滤数组值并返回新数组? [复制]

    这个问题在这里已经有答案了 我有两个数组 all languages and taken languages 第一个包含所有语言 例如 200 种或其他语言 第二个包含之前选择的语言 从 0 到 200 种 我需要删除所有已采用的语言 ta
  • 防止控制台应用程序中的内存工作集最小化?

    我想防止控制台应用程序中的内存工作集最小化 在Windows应用程序中 我可以这样做覆盖 SC MINIMIZE 消息 http support microsoft com kb 293215 en us fr 1 但是 如何在控制台应用程
  • Linux 上的 RTLD_LOCAL 和dynamic_cast

    我们有一个由应用程序中的一些共享库构成的插件 我们需要在应用程序运行时更新它 出于性能原因 我们在卸载旧插件之前加载并开始使用新插件 并且只有当所有线程都使用旧插件完成后 我们才卸载它 由于新插件和旧插件的库具有相同的符号 我们dlopen
  • 保证复制省略是否适用于函数参数?

    如果我理解正确的话 从 C 17 开始 这段代码现在要求不进行任何复制 Foo myfunc void return Foo auto foo myfunc no copy 函数参数也是如此吗 下面的代码中的副本会被优化掉吗 Foo myf
  • LinkLabel 无下划线 - Compact Framework

    我正在使用 Microsoft Compact Framework 开发 Windows CE 应用程序 我必须使用 LinkLabel 它必须是白色且没有下划线 因此 在设计器中 我将字体颜色修改为白色 并在字体对话框中取消选中 下划线
  • .NET 和 Mono 之间的开发差异

    我正在研究 Mono 和 NET C 将来当项目开发时我们需要在 Linux 服务器上运行代码 此时我一直在研究 ASP NET MVC 和 Mono 我运行 Ubuntu 发行版 想要开发 Web 应用程序 其他一些开发人员使用 Wind
  • 以编程方式创建 Blob 存储容器

    我有一个要求 即在创建公司时 在我的 storageaccount 中创建关联的 blob 存储容器 并将容器名称设置为传入的字符串变量 我已尝试以下操作 public void AddCompanyStorage string subDo
  • Xamarin Forms Binding - 访问父属性

    我无法访问页面的 ViewModel 属性以便将其绑定到 IsVisible 属性 如果我不设置 BindingContext 我只能绑定它 有没有办法可以在设置 BindingContext 的同时访问页面的 viewmodel root
  • C:设置变量范围内所有位的最有效方法

    让我们来int举个例子 int SetBitWithinRange const unsigned from const unsigned to To be implemented SetBitWithinRange应该返回一个int其中所有
  • PHP 中根据相似值对数组进行分组

    我有一个具有以下结构的数组
  • 在 C# 的 WebAPI 中的 ApiController 上使用“传输编码:分块”提供数据

    我需要服务分块传输使用编码数据API控制器 因为我无权访问HttpContext or the Http请求 我有点不知道在哪里写入响应以及在哪里刷新它 设置如下 public class MyController ApiControlle
  • 如何获取带有某个属性注释的所有属性?

    我刚刚从 Roslyn 开始 我想找到所有用属性名称 OneToOne 注释的属性 我启动了 SyntaxVisualizer 并能够获取对该节点的引用 但我想知道是否有更简单的方法来实现此目的 这就是我所拥有的 var prop docu
  • Array.of 与“[ ]”。何时使用 Array.of 而不是“[ ]”?

    当我发现时我正在读一些书Array of https developer mozilla org en docs Web JavaScript Reference Global Objects Array of 根据 MDN Array o
  • GSON 将带有日历的对象反序列化为带有 Mongo 日期的 json 并返回

    我有一些实体 其中包含一些日历属性 我想以将它们存储为 GSON 序列化 JSON 中的日期的方式对其进行序列化 因为 Mongo 可以将 date 存储为 new ISODate 我们通常通过使用 ExclusionStrategy 忽略
  • 从后面的代码添加外部 css 文件

    我有一个 CSS 文件 例如 SomeStyle css 我是否可以将此样式表文档从其代码隐藏应用到 aspx 页面 您可以将文字控件添加到标头控件中 Page Header Controls Add new System Web UI L
  • 声明一个负长度的数组

    当创建负长度数组时 C 中会发生什么 例如 int n 35 int testArray n for int i 0 i lt 10 i testArray i i 1 这段代码将编译 并且启用 Wall 时不会出现警告 并且似乎您可以分配

随机推荐

  • 无法在特定 div 上滚动来触发 jquery 函数

    简短版本 这有效 document on click Container function 这不会 document on scroll Container function 长版 很抱歉 发布代码片段是不可行的 因为它是一个复杂的类似应用
  • 类中的部分评估类型

    这是我提出的问题的具体版本here https stackoverflow com questions 60072003 reordering type parameters in haskell 我有一个算法 可以产生一些输出 并且可以产
  • 使用鼠标选择要捕获的区域

    我正在制作一个基于Java的屏幕截图应用程序 当您按下键盘上的组合键时 我想这样做这个视频 http www youtube com watch v bJ6VbbpQ0XY发生在您在屏幕上选择区域的位置 并且它会拍摄所选区域的屏幕截图 如何
  • Google 搜索查询中参数的含义? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有没有关于 Google 查询中的参数含义的资源 有没有分析过 Google 搜索页面的内部运作方式 例子是 http www googl
  • 如何使用eclipse进行C#开发? [复制]

    这个问题在这里已经有答案了 可以使用eclipse进行C 开发吗 如果可以的话 该怎么办呢 您最喜欢的组合是什么 虽然我见过一些半成品的插件 但我不相信有任何东西可以做到这一点close到 Eclipse 中的 Java 工具 如果您使用的
  • 使用 jquery-1.4.1.js 访问被拒绝

    我正在使用 VS2010 和 jquery 1 4 1 js 版本 我尝试访问 WCF 服务 但出现奇怪的错误 访问被拒绝 in jquery 1 4 1 js在页码处4982 jquery 1 4 1 js Open the socket
  • 清除控制台缓冲区

    我正在 VS2008 中编写一个示例控制台应用程序 现在我有一个Console WriteLine 在屏幕上显示输出的方法 然后有Console ReadKey 等待用户结束应用程序 If I press Enter while the C
  • 如何从服务类调用组件方法 - Angular

    我试图从服务类调用组件方法 但收到类似 错误类型错误 无法读取未定义的属性 测试 的错误 但是我遇到了类似的问题 但主要解释了组件到组件的调用 所以我没有正确理解 例子 测试组件 ts Component selector componen
  • 考虑到指令具有不同的长度,CPU 如何知道下一条指令应该读取多少字节?

    所以我正在读一篇论文 其中他们说静态反汇编二进制代码是不可判定的 因为一系列字节可以用多种可能的方式表示 如图所示 其 x86 所以我的问题是 那么CPU是如何执行这个的呢 例如 在图中 当我们到达 C3 之后时 它如何知道下一条指令应该读
  • 如何动态覆盖__setitem__? (无子类)

    我无法覆盖某些内置函数 例如 setitem Python2 7 虽然我测试的之前版本也出现同样的情况 虽然我知道这很容易通过子类化来完成 但这不是我想要的 我需要能够动态地重写这些方法 显然 当我的班级是 的子类时object 被重写的方
  • iOS Swift:将打印和调试打印写入文件

    晚上 是否可以将所有打印和调试打印保存在文件中 我想要记录我的应用程序所做的事情 即使它不是从 Xcode 启动的 我正在考虑重写 print 和 debugPrint 方法并将输入写入文件 Thanks Swift 标准库中有以下方法 f
  • ConvergenceWarning:lbfgs 未能收敛(状态 = 1):停止:总数迭代次数达到限制

    我有一个由数字和分类数据组成的数据集 我想根据患者的医疗特征预测患者的不良结果 我为我的数据集定义了一个预测管道 如下所示 X dataset drop columns target y dataset target define cate
  • 在空行上将文本文件拆分为字符串

    我想读取本地的一个txt文件 读取这个文件中的文本 之后 我想将整个文本拆分为字符串 如下例所示 例子 可以说文件包含 abcdef ghijkl aededd ededed ededfe efefeef efefeff 我想将此文本拆分为
  • Mingw64-w64 属性(格式)和 标头

    交叉编译时 我在让 cinttypes 在 mingw64 w64 上正常工作时遇到严重问题 我已经将其简化为在 docker 中运行的最小示例 inttypes test cpp include
  • XNA:当前顶点声明不包括当前顶点着色器所需的所有元素。 Normal0 缺失

    嘿 我遇到了一点麻烦 我使用 xna 已经有一段时间了 但我对 3D 完全陌生 我正在逐字跟踪 msdn 网站上 winformsgraphicsdevice 示例中的代码 它有一个可以在屏幕上绘制一个原始三角形的控件 就这么简单 但我在这
  • Safari 未检测到我的扩展证书

    我已注册 Safari 开发计划并拥有有效的 Apple ID 我已按照Apple提供的所有步骤进行操作 问题是 Windows XP Service Pack 2 无法识别命令 certreq 而说明表明它可以在任何 Windows 计算
  • 使用 UNIX 机器文件和目录选项卡自动完成的 Windows 应用程序

    Unix Linux 支持按 tab 时自动完成文件和目录 我需要在我的 Windows 应用程序中创建此功能 我有一个用于用户输入文件名的文本字段 我想响应 制表符 按下 就像我们在 Unix 控制台中一样 如果有一个选项 自动完成 一些
  • 移动网站检测服务器端与客户端

    谁能推荐检测移动设备访问网站的最佳方法 我们希望重定向到移动版本 而不是由于 CMS 限制而重新设计现有页面 我们还需要能够根据要求在移动设备上返回完整网站的选项 我们有一个 net 服务器 但不是 net 开发人员 因此必须为服务器端完成
  • 是否可以使用 EclipseLink 输出生成的 SQL,而无需增加日志详细程度?

    我想在开发过程中将 EclipseLink 生成的 SQL 输出到控制台 但是 我只能使用日志记录级别 FINE 来执行此操作 我有一个由许多类组成的复杂域模型 当日志详细程度处于 FINE 级别时 部署会花费相当多的时间 因为 Eclip
  • C# Mongodb 多个对象数组文档的笛卡尔积

    尝试使用 C Linq 甚至原始 Mongodb 查询本身来了解如何将多个数组连接为笛卡尔积 举例来说 我有一个集合 我将其过滤为以下两个文档 movie starwars showday monday movie batman showd