【问题标题】:mongodb: Is it possible to do a range search on the first item in an array of arraysmongodb:是否可以对数组数组中的第一项进行范围搜索
【发布时间】:2020-09-03 21:47:44
【问题描述】:

这是一个记录的简化示例,

"id" : 1
"foo" : [
         [ 10:30,
           2,
           4
         ],
         [ 11:30,
           3,
           5
         ],
          ... 
        ]

foo 是一个数组数组。

是否可以创建一个查询来使用 $gt 和 $lt 指定范围来仅比较每个内部数组的第一个元素?

我知道我可以使用 $elemMatch 找到完全匹配,

db.collection.find('foo' : { $elemMatch : { $elemMatch : { $in : ['11:30'] } } } )

我想查找所有包含时间在 10:00 到 12:00 之间的记录作为示例。

【问题讨论】:

  • 当您说“所有记录”时,您是指文档,即整个示例文档是一条记录,因此如果至少有一个元素匹配,则应返回它,还是您的意思是要返回文档中只有 foo 的元素而不是匹配?
  • 11:30这是什么格式,这是时间吗?
  • @varman 对不起,格式并不重要,只是为了说明内部数组中的第一个元素是我要检查的唯一内容。它可以是 bob 或 4 或任何东西。我希望查询只检查内部数组中的第 0 个元素。
  • @joe 如果内部数组的第 0 个元素中的任何一个在范围内,我想要整个记录。
  • @tony 格式对于获得您的结果很重要。是字符串还是数字?

标签: arrays mongodb find


【解决方案1】:

您可以使用聚合获得此行为。

首先使用$addfields创建一个新字段使用$reduce迭代外部数组,$arrayElemAt选择内部数组的元素,返回累加器的$or与当前的测试元素。

然后$match这个新字段选择匹配值的文档。

请注意,如果您希望能够查询某个时间范围,则需要将小于 10 的小时数补零,或者使用日期类型。

db.collection.aggregate([
  {$addFields:{
      matches: {
        $reduce: {
           input: "$foo",
           initialValue: 0,
           in: {
             $cond: {
               if: {$eq: [
                          "11:30",
                          {$arrayElemAt: [ "$$this", 0]}
               ]},
               then: {$sum: ["$$value", 1]},
               else: "$$value"
             }
           }
        }
      }
  }},
  {$match: { matches: {$gt: 0}}
])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 2019-10-10
    • 1970-01-01
    • 2019-01-22
    • 2012-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多