如何在MongoDB的嵌套阵列上求发?

发布于 2025-02-12 11:33:30 字数 1072 浏览 2 评论 0 原文

受另一个

假设我的文档看起来像:

{
    _id: ObjectId("5a934e000102030405000000"),
    events: [
      {
        status: 0,
        timestamp: ISODate("2022-05-29T13:26:00Z")
      },
      {
        status: 8,
        timestamp: ISODate("2022-05-29T14:41:00Z")
      },
      {
        status: 4,
        timestamp: ISODate("2022-05-31T10:13:00Z")
      },
      {
        status: 3,
        timestamp: ISODate("2022-05-31T10:18:00Z")
      }
    ]
  }

我想夫妇:

  {
    _id: ObjectId("5a934e000102030405000000"),
    couples: [
      [
        {
          mod: 0,
          status: 0,
          timestamp: ISODate("2022-05-29T13:26:00Z")
        },
        {
          mod: 1,
          status: 8,
          timestamp: ISODate("2022-05-29T14:41:00Z")
        }
      ],
      [
        {
          mod: 0,
          status: 4,
          timestamp: ISODate("2022-05-31T10:13:00Z")
        },
        {
          mod: 1,
          status: 3,
          timestamp: ISODate("2022-05-31T10:18:00Z")
        }
      ]
    ]
  }

Inspired by another question I was looking for a common way to couple items in a nested array, so the 1st item will be coupled with the 2nd item, and the 3rd item will be coupled with the 4th item.

Assuming my document looks like:

{
    _id: ObjectId("5a934e000102030405000000"),
    events: [
      {
        status: 0,
        timestamp: ISODate("2022-05-29T13:26:00Z")
      },
      {
        status: 8,
        timestamp: ISODate("2022-05-29T14:41:00Z")
      },
      {
        status: 4,
        timestamp: ISODate("2022-05-31T10:13:00Z")
      },
      {
        status: 3,
        timestamp: ISODate("2022-05-31T10:18:00Z")
      }
    ]
  }

And I want to couple the items:

  {
    _id: ObjectId("5a934e000102030405000000"),
    couples: [
      [
        {
          mod: 0,
          status: 0,
          timestamp: ISODate("2022-05-29T13:26:00Z")
        },
        {
          mod: 1,
          status: 8,
          timestamp: ISODate("2022-05-29T14:41:00Z")
        }
      ],
      [
        {
          mod: 0,
          status: 4,
          timestamp: ISODate("2022-05-31T10:13:00Z")
        },
        {
          mod: 1,
          status: 3,
          timestamp: ISODate("2022-05-31T10:18:00Z")
        }
      ]
    ]
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自由范儿 2025-02-19 11:33:30

由于MongoDB版本4.4*,一个选项是将聚合管道与 $降低 $ mod $ filter $ zip

  1. $ ydre 带有 $ mod 添加一个新 mod 字段到每个项目,带有Value 0 每个奇数索引(1, 3,5,...)和值 1 偶数索引(2,4,6,...
  2. ) > mod value
  3. <代码> $ zip 这两个阵列到一对夫妻的数组,
db.collection.aggregate([
  {
    $project: {
      events: {
        $reduce: {
          input: "$events",
          initialValue: [],
          in: {$concatArrays: [
              "$value",
              [
                {
                  timestamp: "$this.timestamp",
                  status: "$this.status",
                  mod: {$mod: [{$size: "$value"}, 2]}
                }
              ]
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      firstEvent: {$filter: {input: "$events", cond: {$eq: ["$this.mod", 0]}}},
      secondEvent: {$filter: {input: "$events", cond: {$eq: ["$this.mod", 1]}}}
    }
  },
  {$project: {couples: {$zip: {inputs: ["$firstEvent", "$secondEvent"]}}}}
])

看看它在 playground示例示例

*与较旧的mongodb版本,3.4或更高版本, $ mod 可以是替换为“手动” mod 计算。

Since mongoDB version 4.4*, One option is to use an aggregation pipeline with $reduce, $mod, $filter and $zip:

  1. $reduce with $mod to add a new mod field to each item, with value 0 to each odd index (1, 3, 5,...) and value 1 to each even index (2, 4, 6,...)
  2. $fiter into two arrays according to the mod value
  3. $zip these two arrays to one array of couples
db.collection.aggregate([
  {
    $project: {
      events: {
        $reduce: {
          input: "$events",
          initialValue: [],
          in: {$concatArrays: [
              "$value",
              [
                {
                  timestamp: "$this.timestamp",
                  status: "$this.status",
                  mod: {$mod: [{$size: "$value"}, 2]}
                }
              ]
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      firstEvent: {$filter: {input: "$events", cond: {$eq: ["$this.mod", 0]}}},
      secondEvent: {$filter: {input: "$events", cond: {$eq: ["$this.mod", 1]}}}
    }
  },
  {$project: {couples: {$zip: {inputs: ["$firstEvent", "$secondEvent"]}}}}
])

See how it works on the playground example

*With older mongoDB versions, 3.4 or higher, the $mod can be replaces with a "manual" mod calculation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文