使用$ elemMatch查询数组索引

时间:2018-10-07 06:15:19

标签: mongodb mongoose

我的收藏的结构如下,

"data":[ 
        [ 
            ISODate("2018-10-01T03:45:00.000Z"), 
            752.5, 
            752.9, 
            746.5, 
            746.5, 
        ], 
        [ 
            ISODate("2018-10-02T03:46:00.000Z"), 
            746.5, 
            750.9, 
            746.5, 
            749.95, 
        ],...
     ]

如何查询集合,以便仅返回“数据”数组的那些子数组,其中某些索引处的元素与特定条件匹配。

例如,要查找索引1处的元素大于“ 750”的数组,

db.collections('mycol').find({
            "data":
            {
                "$elemMatch":
                {
                    "$.[1]":
                    {
                        "$gte": 750
                    }
                }
            }
        });

显然,这是行不通的,因为“ $。[1]”不是指定索引1的正确方法,那么我应该用什么代替它呢?

2 个答案:

答案 0 :(得分:1)

一种获取此索引并匹配特定索引(在这种情况下为1)的方法是:

db.collection.find({
  "data": {
    "$elemMatch": {
      "1": {
        "$gte": 750
      }
    }
  }
},
{
  "data.$": 1
})

查看here

如果您不关心索引,而只想检查其中的值是否大于750

db.collection.find({
  "data": {
    "$elemMatch": {
      "$elemMatch": {
        "$gte": 750
      }
    }
  }
},
{
  "data.$": 1
})

查看此here

要获得多重使用汇总,因为使用$ elemMatch,您不能获得多个值:

db.collection.aggregate([
  {
    $unwind: "$data"
  },
  {
    $match: {
      "data": {
        $gte: 740
      }
    }
  }
])

答案 1 :(得分:0)

db.collection.aggregate([
  {
    $addFields: {
      "data": {
        $filter: {
          input: "$data",
          as: "d",
          cond: {
            $gte: [
              { $arrayElemAt: [ "$$d", 1] },
              750
            ]
          }
        }
      }
    }
  }
])

此解决方案终于对我有用。它给出了所有匹配的嵌套子数组。

说明

$ addFields 用于在输出中添加字段,但是我们也可以使用它来覆盖将在输出中存在的现有字段。因此,由于输出中的 data 字段将包含所有数组,因此我们将 data 字段替换为新的 data 字段,该字段仅包含匹配的数组给定的条件。

$ filter 用于此目的,它将从给定的数组集中仅返回满足 cond 参数中描述的条件的那些数组。

由于数组没有任何标识符/键,因此我们使用 $ arrayElemAt 获取数组中给定索引处的值,然后使用常规查询参数进行条件过滤。完成此操作后,仅返回满足条件的那些数组。