1

MongoDB 必须$indexOfArray让你找到元素的数组索引,例如:

$indexOfArray: ["$article.date", ISODate("2019-03-29")]

是否可以一起使用比较运算符$indexOfArray,例如:

$indexOfArray: ["$article.date", {$gte: ISODate("2019-03-29")}]
4

1 回答 1

2

并非不可能,$indexOfArray因为它只会寻找与表达式的相等匹配作为第二个参数。

相反,您可以制作这样的构造:

db.data.insertOne({
    "_id" : ObjectId("5ca01e301a97dd8b468b3f55"),
    "array" : [
            ISODate("2018-03-01T00:00:00Z"),
            ISODate("2018-03-02T00:00:00Z"),
            ISODate("2018-03-03T00:00:00Z")
    ]
})

db.data.aggregate([
  { "$addFields": {
    "matchedIndex": {
      "$let": {
        "vars": {
          "matched": {
            "$arrayElemAt": [
              { "$filter": {
                "input": {
                  "$zip": {
                    "inputs": [ "$array", { "$range": [ 0, { "$size": "$array" } ] }]
                  }
                },
                "cond": { "$gte": [ { "$arrayElemAt": ["$$this", 0] }, new Date("2018-03-02") ] }
              }},
              0
            ]
          }
        },
        "in": {
          "$arrayElemAt": [{ "$ifNull": [ "$$matched", [0,-1] ] },1]
        }
      }
    }
  }}
])

这将返回$gteDate("2018-03-02")

{
        "_id" : ObjectId("5ca01e301a97dd8b468b3f55"),
        "array" : [
                ISODate("2018-03-01T00:00:00Z"),
                ISODate("2018-03-02T00:00:00Z"),
                ISODate("2018-03-03T00:00:00Z")
        ],
        "matchedIndex" : 1
}

或者-1不符合条件的地方为了符合$indexOfArray

基本前提是$zip为了“配对”与从数组$range和数组生成的数组索引位置$size。这可以被提供给一个$filter条件,它将所有匹配的元素返回到提供的条件。这是通过使用匹配指定条件的“对”的第一个元素(作为原始数组内容)$arrayElemAt$gte

{ "$gte": [ { "$arrayElemAt": ["$$this", 0] }, new Date("2018-03-02") ] }

$filter返回(在 的情况下$gte)之后的所有元素或未找到任何内容的空数组。与您一致,$indexOfArray您只需要第一个 match$arrayElemAt ,这是通过在该位置的输出上进行另一个包装来完成的0

由于结果可能是一个省略的值(这是由 发生的$arrayElemAt: [[], 0]),因此您使用 [来测试结果,并在未定义输出的情况下$ifNull][8]将一个双元素数组以 a 作为第二个元素传回。-1在任何一种情况下,“配对”数组都会1通过再次提取第二个元素(索引)$arrayElemAt以获得条件的第一个匹配索引

当然,既然你想引用整个表达式,它最后在 a 中读起来会更干净一些$let,但这是可选的,因为你可以“内联”与$ifNullif 需要。

所以这是可能的,它只是比在$indexOfArray.

请注意,任何实际上为相等匹配返回单个值的表达式都可以。但是由于像return a这样的运算符,那么它不等于数组中的任何值,因此你需要使用然后提取的那种处理。$gteboolean$filter

于 2019-03-31T02:33:34.480 回答