MongoDB 必须$indexOfArray
让你找到元素的数组索引,例如:
$indexOfArray: ["$article.date", ISODate("2019-03-29")]
是否可以一起使用比较运算符$indexOfArray
,例如:
$indexOfArray: ["$article.date", {$gte: ISODate("2019-03-29")}]
MongoDB 必须$indexOfArray
让你找到元素的数组索引,例如:
$indexOfArray: ["$article.date", ISODate("2019-03-29")]
是否可以一起使用比较运算符$indexOfArray
,例如:
$indexOfArray: ["$article.date", {$gte: ISODate("2019-03-29")}]
并非不可能,$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]
}
}
}
}}
])
这将返回$gte
:Date("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
,但这是可选的,因为你可以“内联”与$ifNull
if 需要。
所以这是可能的,它只是比在$indexOfArray
.
请注意,任何实际上为相等匹配返回单个值的表达式都可以。但是由于像return a这样的运算符,那么它不等于数组中的任何值,因此你需要使用然后提取的那种处理。$gte
boolean
$filter