簡體   English   中英

MongoDB:根據位置范圍更新數組的子集

[英]MongoDB: Update a subset of an array based on position range

我需要使用批量寫入操作更新許多 MongoDB 文檔中數組中的值(每個文檔的新數組都不同)。 我的問題是:有沒有辦法根據元素位置范圍更新數組值的子集,傳遞一個數組來替換這些值

這是我的文檔結構:

{
year: 2020,
location_id: 1,
values: [1.2 0 0 5.2 1.02 8 0 0 0 0 1.2 4]
}

假設我想用這個新數組替換第一個值以外的所有值:

[1 2 5.1 2 4 0 87 1 0.2 2 9]

即,“價值觀”應該變成:

[1.2 1 2 5.1 2 4 0 87 1 0.2 2 9]

我知道如何完全替換數組:

UpdateOne({'year': 2020, 'location_id': 1}, {'$set': {'values': [1.2 1 2 5.1 2 4 0 87 1 0.2 2 9]}})

但是這第一個選項要求我首先查詢集合以獲取數組的第一個值。 我想避免這種情況。

我也知道如何用 11 個單獨的 updateone 命令(這里是在 python 中)一個一個地替換值:

col.bulk_write([UpdateOne({'year': 2020, 'location_id': 1}, {'$set': {'values.1': 1}}),
                UpdateOne({'year': 2020, 'location_id': 1}, {'$set': {'values.2': 2}}),
                .... ,
                UpdateOne({'year': 2020, 'location_id': 1}, {'$set': {'values.11': 9}})],
               ordered = False)

這第二個選項意味着我將每天發送數百萬個 UpdateOne 語句,因為我每天都有數百萬個文檔需要更新,而且要更新的數組比這個簡單示例中的要大得多。 我也不是很喜歡。

請注意,一個相關的問題是:第二個選項是否會使我的服務器過載,或者它是否不會比第一個選項占用更多資源? 第一個選項意味着使用 300'000 個 updateOne 語句進行批量寫入,每個語句修改一個 365 長的數組,而第二個選項將意味着 300'000*364 個 updateOne 語句,每個語句修改一個數組元素。

我希望能夠執行以下操作:

UpdateOne({'year': 2020, 'location_id': 1}, {'$set': {'values.1-end': [1 2 5.01 2 4 0 87 1 0.2 2 9]}})

即,指定要由提供的數組替換的數組位置范圍。 到目前為止,我找不到如何做到這一點。 這將導致包含 300'000 個 updateOne 語句的批量寫入,每個語句都准確地替換那些需要替換的 364 個值。

注意:在此示例中,它替換了“除第一個值之外的所有值”,但它也可能是“除最后一個值之外的所有值”。 也可能“用這個長度為 6 的數組替換位置 4 到 9 的元素”。 我正在用python編寫我的代碼。

您可以使用聚合管道並將其用於更新:

db.collection.updateOne(
   {'year': 2020, 'location_id': 1},
   [{
      $set: {
         values: {
            $concatArrays: [
               [{ $arrayElemAt: ["$values", 0] }],
               [1, 2, 5.1, 2, 4, 0, 87, 1, 0.2, 2, 9]
            ]
         }
      }
   }]
)

對於諸如“用這個長度為 6 的數組替換位置 4 到 9 的元素”之類的操作,您也可以使用$slice

運算符$range也可能有所幫助,請參閱如何在聚合框架中按位置修改數組中的值

暫無
暫無

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

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