arrays - 如何在 MongoDB 中同时查询两个数组?

标签 arrays mongodb mongodb-query nosql document

我有以下文档,其中每个文档都有字段 valuesdates,它们是数组。这些数组在每个文档中始终具有相同的大小,这意味着 dates 中的每个值对应于 values 中的值:

[
  {
    _id: "Stock1",
    values: [
      1,
      2,
      3
    ],
    dates: [
      ISODate("2000-01-01"),
      ISODate("2010-01-01"),
      ISODate("2020-01-01")
    ]
  },
  {
    _id: "Stock2",
    values: [
      4,
      5,
    ],
    dates: [
      ISODate("2000-01-01"),
      ISODate("2010-01-01")
    ]
  },
  {
    _id: "Stock3",
    values: [
      7,
      8,
      9
    ],
    dates: [
      ISODate("2000-01-01"),
      ISODate("2010-01-01"),
      ISODate("2020-01-01")
    ]
  }
]

我想查询我的文档,以便在 dates“2010-01-01”和 dates“2020-”之间获得 01-01”(包含)仅适用于“Stock1”和“Stock3”,即我想以:

[
  {
    _id: "Stock1",
    values: [
      2,
      3
    ],
    dates: [
      ISODate("2010-01-01"),
      ISODate("2020-01-01")
    ]
  },
  {
    _id: "Stock3",
    values: [
      8,
      9
    ],
    dates: [
      ISODate("2010-01-01"),
      ISODate("2020-01-01")
    ]
  }
]

目前,我正在做以下事情:

db.collection.aggregate([
  {
    $match: {
      _id: {
        $in: [
          "Stock1",
          "Stock3"
        ]
      }
    }
  },
  {
    $unwind: {
      path: "$dates",
      includeArrayIndex: "date_index"
    }
  },
  {
    $match: {
      dates: {
        $gte: ISODate("2010-01-01"),
        $lte: ISODate("2020-01-01")
      }
    }
  },
  {
    $unwind: {
      path: "$values",
      includeArrayIndex: "value_index"
    }
  },
  {
    $match: {
      $expr: {
        $eq: [
          "$date_index",
          "$value_index"
        ]
      }
    }
  },
  {
    $project: {
      date_index: 0,
      value_index: 0
    }
  }
])

但我还没有到那一步。此外,管道看起来很长且次优。有更好的方法吗?最后,我首先在 dates 上使用 unwind,然后在 values 上再次使用 unwind 之前进行过滤:这是为了避免管道中的大量文档太大,因为数组 datesvalues 可能会很大。

如有任何帮助,我们将不胜感激!

最佳答案

查询

  • 匹配以仅保留 "Stock1","Stock3"
  • 过滤日期索引 (range (size "$dates")),只获取日期在 [2010-2020] 范围内的元素的索引
  • 2 映射以从 datesvalues 中获取那些过滤的索引

*我们可以像 1 个 reduce 一样完成所有操作,但它会嵌套且代码更复杂,而且 $concatArrays 很慢,将数组减少到数组并不是一个好主意。波纹管更简单,甚至可以用于非常大的阵列。

PlayMongo

aggregate(
[{"$match": {"_id": { "$in": ["Stock1","Stock3"]}}}
 {"$set": 
    {"indexes": 
      {"$filter": 
        {"input": {"$range": [0, {"$size": "$dates"}]},
          "cond": 
          {"$and": 
            [{"$gte": 
                [{"$arrayElemAt": ["$dates", "$$this"]},
                  ISODate("2010-01-01T00:00:00Z")]},
              {"$lte": 
                [{"$arrayElemAt": ["$dates", "$$this"]},
                  ISODate("2020-01-01T00:00:00Z")]}]}}}}},
  {"$set": 
    {"dates": 
      {"$map": 
        {"input": "$indexes",
          "in": {"$arrayElemAt": ["$dates", "$$this"]}}}}},
  {"$set": 
    {"values": 
      {"$map": 
        {"input": "$indexes",
          "in": {"$arrayElemAt": ["$values", "$$this"]}}}}},
  {"$unset": ["indexes"]}])

关于arrays - 如何在 MongoDB 中同时查询两个数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70034461/

相关文章:

mongodb - Mongoid 按值或默认值查询

node.js - findAndModify() 在 Mongoose 中给出异常

arrays - ARM 汇编数组

ios - 通过索引从数组中获取对象,即从另一个数组中获取

php - 如何在mongodb数据库中存储特殊字符?

linux - MongoDb 和 YCSB : workload A: why update latency is so small?

node.js - mongo 查询 - 属性是否存在?

mongodb - 了解性能 : mongo aggregation vs count

arrays - 使用 Swift4 Codable 解码数组

arrays - 从 n 个排序数组中找到第 k 个最小的数字