You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB中为每个文档统计数组内各值的出现次数

Hey there! Let's figure out how to add that occurrences field you need. You want to count each value's frequency in the types array and store it as an object—here are two straightforward ways to do this with MongoDB:

1. Aggregation Query (Real-Time Calculation, No Permanent Changes)

If you just need to retrieve documents with the occurrences field without modifying your collection, use the aggregation framework with $reduce (this is more efficient than unwinding large arrays):

db.collection.aggregate([
  {
    $addFields: {
      occurrences: {
        $arrayToObject: {
          $reduce: {
            input: "$types",
            initialValue: [],
            in: {
              $let: {
                vars: {
                  existingEntry: { $indexOfArray: ["$$value.k", "$$this"] }
                },
                in: {
                  $cond: {
                    if: { $ne: ["$$existingEntry", -1] },
                    then: {
                      $map: {
                        input: "$$value",
                        as: "item",
                        in: {
                          $cond: {
                            if: { $eq: ["$$item.k", "$$this"] },
                            then: { k: "$$item.k", v: { $add: ["$$item.v", 1] } },
                            else: "$$item"
                          }
                        }
                      }
                    },
                    else: { $concatArrays: ["$$value", [{ k: "$$this", v: 1 }]] }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  // Optional: Convert numeric counts to strings (matches your desired output)
  {
    $addFields: {
      occurrences: {
        $arrayToObject: {
          $map: {
            input: { $objectToArray: "$occurrences" },
            as: "count",
            in: { k: "$$count.k", v: { $toString: "$$count.v" } }
          }
        }
      }
    }
  }
])

How this works:

  • $reduce iterates over each element in the types array, building up an array of key-value pairs where the key is the type and the value is its count.
  • $arrayToObject converts that array into the occurrences object you want.
  • The optional final step converts numeric counts to strings to match your exact desired output.

2. Permanent Update (Add occurrences to Documents)

If you want to permanently add the occurrences field to every document in your collection (MongoDB 4.2+ required, since we use an aggregation pipeline in updateMany):

db.collection.updateMany(
  {}, // Matches all documents in the collection
  [
    {
      $set: {
        occurrences: {
          $arrayToObject: {
            $reduce: {
              input: "$types",
              initialValue: [],
              in: {
                $let: {
                  vars: {
                    existingEntry: { $indexOfArray: ["$$value.k", "$$this"] }
                  },
                  in: {
                    $cond: {
                      if: { $ne: ["$$existingEntry", -1] },
                      then: {
                        $map: {
                          input: "$$value",
                          as: "item",
                          in: {
                            $cond: {
                              if: { $eq: ["$$item.k", "$$this"] },
                              then: { k: "$$item.k", v: { $add: ["$$item.v", 1] } },
                              else: "$$item"
                            }
                          }
                        }
                      },
                      else: { $concatArrays: ["$$value", [{ k: "$$this", v: 1 }]] }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    // Optional: Convert counts to strings
    {
      $set: {
        occurrences: {
          $arrayToObject: {
            $map: {
              input: { $objectToArray: "$occurrences" },
              as: "count",
              in: { k: "$$count.k", v: { $toString: "$$count.v" } }
            }
          }
        }
      }
    }
  ]
)

Notes for older MongoDB versions:

If you're on a version before 4.2 (which doesn't support aggregation pipelines in updates), you can either:

  • Use a client-side script (e.g., Node.js, Python) to fetch each document, calculate the counts, and update the document.
  • Run the aggregation query from Method 1, export the results, and re-insert them into the collection (make sure to handle _id correctly to avoid duplicates).

内容的提问来源于stack exchange,提问作者sabfon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:25:06