MongoDB聚合,以循环方式组合2个阵列

MongoDB聚合,以循环方式组合2个阵列,mongodb,Mongodb,我在MongoDB集合中有如下数据: [ { “_id”:1, “类型”:“大”, “字段”:[11,12,13], “项目”:[21、22、23] }, { “_id”:2, “类型”:“小”, “字段”:[14,15], “项目”:[24,25] }, { “_id”:3, “类型”:“小”, “字段”:[], “项目”:[41,42] }, { “_id”:4, “类型”:“小”, “字段”:[31,32,33], “项目”:[] } ] 我的任务是按照如下程序返回数据: 对于集合中的每

我在MongoDB集合中有如下数据:

[
{
“_id”:1,
“类型”:“大”,
“字段”:[11,12,13],
“项目”:[21、22、23]
},
{
“_id”:2,
“类型”:“小”,
“字段”:[14,15],
“项目”:[24,25]
},
{
“_id”:3,
“类型”:“小”,
“字段”:[],
“项目”:[41,42]
},
{
“_id”:4,
“类型”:“小”,
“字段”:[31,32,33],
“项目”:[]
}
]
我的任务是按照如下程序返回数据:

对于集合中的每个文档,从其
字段中获取1个值(如果有),并从其
项中获取1个值(如果有)。将所有结果连接到单个数组中

可以将其概括为以“循环”方式从每个文档中保存的两个数组中选择数据

如何在MongoDB聚合查询中实现这一点?这种逻辑在连接到Mongo服务器的客户端中实现并不困难,但我希望让Mongo负责分页(使用
$skip
$limit
)。我正在使用MongoDB 4.4

结果数据如下所示:

[
{
“价值”:11,
“类型”:“字段”,
“fromId”:1
},
{
“价值”:21,
“类型”:“项目”,
“fromId”:1
},
{
“价值”:14,
“类型”:“字段”,
“fromId”:2
},
{
“价值”:24,
“类型”:“项目”,
“fromId”:2
},
{
“价值”:41,
“类型”:“项目”,
“fromId”:3
},
{
“价值”:31,
“类型”:“字段”,
“fromId”:4
},
]

如果我正确理解你的问题;这应该是一个可行的管道。要实现随机功能,只需调整传递给$arrayElemAt的索引即可

随机化看起来像这样:


那么,你总是抓取这些数组的第一个元素,还是它必须是随机的呢?在这种情况下,它是第一个元素,但我认为当前的逻辑尚未最终确定,将来可能会随机。算法本身有点不够具体;我对这里的各种解决方案持开放态度。我对MongoDB还是新手。语法
{types:[a,b]}
的作用是什么?它只是在投影中创建一个2元素数组(包含
a
b
)吗?是的。通过使用该投影,然后$unwinding它创建的数组,我们基本上将每个文档转换为两个文档,每种类型一个。
db.collection.aggregate([
  {$project: {
     types: [
      {type: "field", values: "$fields"},
      {type: "item", values: "$items"}
    ]
  }},
  {$unwind: '$types'},
  {$project: {
    _id: 0,
    value: {$arrayElemAt: ['$types.values', 0]},
    type: '$types.type',
    fromId: '$_id'
  }},
  {$match: {
    value: {$exists: true}
  }}
])
db.collection.aggregate([
  {$project: {
     types: [
      {type: "field", values: "$fields"},
      {type: "item", values: "$items"}
    ]
  }},
  {$unwind: '$types'},
  {$project: {
    _id: 0,
    value: {$arrayElemAt: [
      '$types.values',
      {$floor: {$multiply: [{$rand: {}}, {$size: '$types.values'}]}}
    ]},
    type: '$types.type',
    fromId: '$_id'
  }},
  {$match: {
    value: {$exists: true}
  }}
])