簡體   English   中英

查找包含數組中特定值但不是最后一個元素的文檔

[英]Find a document that contains a specific value in an array but not if it's the last element

我目前的做法是:

var v = 'Value';
Collection.find({arrayToLookIn: v}).forEach(function(obj) {
  if (obj.arrayToLookIn.indexOf(v) !== obj.arrayToLookIn.length - 1) {
    // do stuff
  }
}

我想知道是否有辦法在find()調用中指定這樣的規則並在沒有內部檢查的情況下執行此操作?

我已經瀏覽了https://docs.mongodb.org/manual/tutorial/query-documents/#match-an-array-element但沒有發現我在尋找什么。

第一個問題,請溫柔:)

你現在可以做什么

您需要$where ,它可以使用 JavaScript 評估來匹配文檔。 所以在這里你要求評估代碼測試每個數組元素,但不是最后一個:

Collection.find({
    "arrayToLookIn": v,
    "$where": function() {
        var array = this.arrayToLookIn;
        array.pop();                    // remove last element
        return array.some(function(el) { return el == 'Value' });
    }
})

請注意,由於它是發送到服務器的 JavaScript,因此需要在該代碼中指定“值”而不是使用變量。 您可以選擇將 JavaScript 代碼構造為“字符串”,以作為文字加入該變量,並將其作為參數提交給$where

請注意,我將離開基本的相等匹配,因為$where無法使用這樣的索引進行匹配,因此它的工作是“過濾”出匹配在最后一個元素上的結果,而不是測試每一個文檔以查找它是否甚至存在。


更好的未來之路

出於好奇,截至目前的 MongoDB 3.0 發布系列,聚合框架並沒有真正有效的方法來做到這一點,因此 JavaScript 評估是更好的選擇。

您目前需要做一些愚蠢的事情,例如在$unwind之后找到$group的最后一個元素,然后在另一個$unwind之后$match出該值。 如果值存在多次,則效率不高且容易出錯。

未來版本將有一個$slice運算符,可以像這樣與$redact

Collection.aggregate([
    // Still wise to do this as mentioned earlier
    { "$match": { "arrayToLookIn": v } },

    // Then only return if the match was not in the last element
    { "$redact": {
        "$cond": {
            "if": {
                "$setIsSubset": [
                    [v],
                    { "$slice": [
                        "$arrayToLookIn",
                        0,
                        { "$subtract": [ { "$size": "$arrayToLookIn" }, 1 ] }
                    ]}
                ]
            },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }
    }}

其中$setIsSubset通過只返回從0$size1元素來比較通過$slice刪除它的最后一個條目的數組。

這應該比$where更有效$where因為它使用本機編碼操作進行比較,當具有該$slice用於聚合的下一個版本可用時。

更不用說$unwind還可以選擇在未來版本中包含索引位置。 但即使添加了它,它仍然不是一個很好的選擇。

暫無
暫無

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

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