【问题标题】:How to match an array in order with intervening elements using a MongoDB aggregation如何使用 MongoDB 聚合按顺序将数组与中间元素匹配
【发布时间】:2020-05-28 16:03:57
【问题描述】:

我有包含一系列事件对象的文档:

  {
    "events": [
      {
        "name": "A"
      },
      {
        "name": "C"
      },
      {
        "name": "D"
      },
      {
        "name": "B"
      },
      {
        "name": "E"
      }
    ]
  },
  {
    "events": [
      {
        "name": "A"
      },
      {
        "name": "B"
      },
      {
        "name": "S"
      },
      {
        "name": "C"
      }
    ]
  }
] 

在这个数组中,我想计算按上述顺序排列的事件数,以及中间事件。例如,我查找顺序 [A,B,C],使用数组 [A,x,x,B,x],我应该数 2,使用 [A,B,x,x,C] 我应该有 3 个。(x 只是其他任何东西的占位符)

我想以数组的形式总结我所有文档的这些信息,其中包含每个元素的匹配数。用前面的例子,我会得到 [2,2,1],A 有 2 个匹配,B 有 2 个匹配,C 有 1 个匹配。

我的 Current 聚合是在 javascript 中生成的,并遵循以下模式:

  • 将文档与包含 A 的事件数组匹配
  • 将数组从 A 切片到数组末尾
  • 统计文档数
  • 将匹配文档的计数附加到汇总数组中
  • 将文档与包含 B 的事件数组匹配
  • 将数组从 B 切到数组末尾
  • 统计文档数

但是,当一个事件没有出现在任何数组中时,它就会失败,因为没有文档,我没有办法存储汇总数组。例如,对于事件数组 [A,x,x,B,x] [A,B,x,x,C] 并尝试匹配 [A,B,D],我希望 [2,2,0 ],但我有 [] 尝试匹配 D 时没有出现,聚合无法继续。

这是我正在使用的聚合:https://mongoplayground.net/p/rEdQD4FbyC4 将匹配的字母 l.75 更改为不在数组中的内容以产生有问题的行为。

那么有没有办法在没有匹配时不丢失我的数据?就像绕过聚合阶段一样,我在 mongoDB 文档中找不到与绕过阶段相关的任何内容。

或者你知道另一种方法吗?

【问题讨论】:

  • 如果您尝试将[A, B, C, D][A, C, x, D, B, x, x] 匹配怎么办?
  • 在这种情况下我应该只匹配 [A, B]

标签: arrays mongodb aggregation-framework


【解决方案1】:

我们最终使用 reduce 来解决我们的问题

reduce 在 events 数组上,对于每个事件,我们都尝试将其与“累加器大小”位置的元素按顺序匹配,如果匹配,则将其添加到累加器中,否则不添加,等等

这里是 mongo 游乐场:https://mongoplayground.net/p/ge4nlFWuLsZ\

  • 我们要匹配的序列在“sequence”字段中
  • 匹配的元素在“匹配”字段中

【讨论】:

    猜你喜欢
    • 2012-08-31
    • 1970-01-01
    • 2020-09-10
    • 2019-07-17
    • 1970-01-01
    • 2017-03-12
    • 2020-12-04
    • 2012-08-23
    • 1970-01-01
    相关资源
    最近更新 更多