簡體   English   中英

查詢所有數組項均大於指定條件的位置

[英]Query where all array items are greater than a specified condition

我有一個包含日期數組的模型。 我使用$gte運算符作為查詢集合的條件,其中日期數組中所有元素都是給定日期的$gte

例如,我有此文檔:

{ dates: [
    ISODate("2016-10-24T22:00:00.000+0000"), 
    ISODate("2017-01-16T23:00:00.000+0000")]
} 

當我運行此查詢{dates: {$gte: new Date()}} ,結果就是整個文檔。 但是我想要一個結果,其中每個數組項都與我的查詢匹配,而不僅僅是一個查詢。

您可以使用$not和比較條件的倒置來實現:

db.test.find({dates: {$not: {$lt: new Date()}}})

因此,這與docs匹配,而不是存在dates元素的值小於當前時間的情況; 換句話說,所有dates值都> =當前時間。

您還可以將聚合框架與$redact管道運算符一起使用,該框架允許您通過$cond運算符處理邏輯條件,並使用特殊操作$$KEEP來“保留”邏輯條件為true或$$PRUNE的文檔。在條件為假的情況下“刪除”文檔。

此操作類似於使用$project管道來選擇集合中的字段,並創建一個新字段來保存邏輯條件查詢的結果,然后再保存隨后的$match ,除了$redact使用單個管道階段,該階段更高效。

至於邏輯條件,您可以使用Set Operators ,因為它們允許表達式對數組執行set操作,並將數組視為set。 這兩個運算符,即$allElementTrue$map運算符可以用作邏輯條件表達式,因為它們的工作方式是,如果數組中的所有元素實際上都是$gte指定的日期,那么這是真的匹配,文檔“保留”。 否則,將其“修剪”並丟棄。


考慮以下示例,這些示例演示了上述概念:

填充測試集

db.test.insert([
    { dates: [
        ISODate("2016-10-24T22:00:00.000+0000"), 
        ISODate("2017-01-16T23:00:00.000+0000")]
    } ,
    { dates: [
        ISODate("2017-01-03T22:00:00.000+0000"), 
        ISODate("2017-01-16T23:00:00.000+0000")]
    } 
])

$redact$setEquals

db.test.aggregate([
    { "$match": { "dates": { "$gte": new Date() } } },
    {
        "$redact": {
            "$cond": [
                { 
                    "$allElementsTrue": {
                        "$map": {
                            "input": "$dates",
                            "as": "date",
                            "in": { "$gte": [ "$$date", new Date() ] }
                        }
                    } 
                },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    }
])

樣本輸出

{
    "_id" : ObjectId("581899dda450d81cb7d87d3a"),
    "dates" : [ 
        ISODate("2017-01-03T22:00:00.000Z"), 
        ISODate("2017-01-16T23:00:00.000Z")
    ]
}

另一種不太優雅的方法是將$where (作為最后的手段)與Array.prototype.every()方法一起使用:

db.test.find({ "$where": function(){ 
    return this.dates.every(function(date) {
        return date >= new Date();
    })}
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM