簡體   English   中英

查詢包含mongodb中某些字段的數組元素的數量

[英]query for number of array elements containing some field in mongodb

我有一些看起來像這樣的文件:

{
   my_array : [
      { 
         name : "...", 
         flag : 1 // optional
      },
      ...
   ]
}

如何查詢恰好其元素之一包含flag字段的文檔?

這將返回my_array長度正好為1的文檔:

db.col.find({ "my_array" : { $size : 1 } })

這將返回文檔,其中至少 my_array的對象之一包含標志字段:

db.col.find({ "my_array.flag" : { $exists : true } })

這將查找標記為大小為1的數組的文檔:

db.col.find({ "my_array.flag" : { $size : 1 } })

我想以某種方式組合前兩個查詢,檢查是否存在某些內部字段,然后查詢過濾后的數組的大小

您可以嘗試$redact$filter進行查詢。

$filter$ifNull保留匹配的元素,后跟$size$redact並將結果與​​1比較以保留,否則刪除文檔。

db.col.aggregate(
    [{
        $match: {
            "my_array.flag": {
                $exists: true
            }
        }
    }, {
        $redact: {
            $cond: {
                if: {
                    $eq: [{
                        $size: {
                            $filter: {
                                input: "$my_array",
                                as: "array",
                                cond: {
                                    $eq: [{
                                        $ifNull: ["$$array.flag", null]
                                    }, "$$array.flag"]
                                }
                            }
                        }
                    }, 1]
                },
                then: "$$KEEP",
                else: "$$PRUNE"
            }
        }
    }]
)

在mongodb中使用聚合框架,

管道階段1:比賽,

          checking for some inner field existence,

         { "my_array.flag" : { $exists : true } }

初級階段2:項目,

         querying for the size of the filtered array,

         {$project:{ "my_array":{$size:"$my_array"}}}

mongoshell命令,

    db.col.aggregate([{
        $match: {
            "my_array.flag": {
                $exists: true
            }
        }
    }, {
        $project: {
            "my_array": {
                $size: "$my_array"
            }
        }
    }])

按照有關使用聚合的當前答案,以下是使用聚合的可行解決方案:

db.col.aggregate([
{ $match : { "my_array.flag" : { $exists : true } } },
{ $unwind : "$my_array" },
{ $match : { "my_array.flag" : { $exists : true } } },
{ $group : { _id : "$_id", count_flags : { $sum : 1 } } },
{ $match : { "count_flags" : 1 } }
])

以下是解釋的步驟:

  1. 篩選僅包含至少一個flag字段的文檔(這將使用我的索引來大大減少我需要處理的文檔數量)
  2. 展開my_array數組,以便能夠將每個元素作為單獨的文檔處理
  3. 從不包含flag元素中過濾分離的文檔
  4. 再次按_id分組,並計算元素(包含flag字段)
  5. 按新的count_flags字段過濾

我不太喜歡這種解決方案,在標准mongo find查詢中似乎應該采取很多步驟來獲得基本支持。

暫無
暫無

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

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