MongoDB查询:键及其不同的值(每个键独立)?

huangapple go评论49阅读模式
英文:

MongoDB query: keys and their distinct values (each key independently)?

问题

  1. 有一种方法可以获取唯一值,例如,对于字段"a":

    [10, 11]
    
  2. 也有一种方法可以获取任意元组的唯一值,例如,对于("b", "c")的配对:

    [
        {"b": 20, "c": 30},
        {"b": 20, "c": 31}
    ]
    

是否有一种方法可以在单个查询中针对每个字段单独查询唯一值?

例如,我可以简单地使用上述查询1三次,分别对应"a"、"b"和"c":

[10, 11]
[20]
[30, 31]

但我猜这可能不够高效,应该有更好的选项。

附加问题: 如果字段列表事先不知道,该如何操作?

理想情况下,单个查询应该返回所有键及其唯一值:

{
    "a": [10, 11],
    "b": [20],
    "c": [30, 31]
}
英文:

If you have this collection of objects:

{ "a": 10, "b": 20, "c": 30 }
{ "a": 11, "b": 20, "c": 31 }
{ "a": 10, "b": 20, "c": 31 }
  1. There is a way to get distinct values, for example, for field "a":

    [10, 11]
    
  2. There is also a way to get distinct values of any tuple, for example, for pairs of ("b", "c"):

    [
        {"b": 20, "c": 30},
        {"b": 20, "c": 31}
    ]
    

Is there a way to query distinct values for each field individually in a single query?

For example, I can simply use query 1 above 3 times for "a", "b", "c":

[10, 11]
[20]
[30, 31]

But I guess it might be less efficient and there should be a better option.

Bonus: How to do it if the list of fields is not known upfront?

Ideally, the single query should return all keys and their distinct values:

{
    "a": [10, 11],
    "b": [20],
    "c": [30, 31]
}

答案1

得分: 1

假设您事先不知道字段的完整列表,您需要使用$objectToArray$$ROOT文档转换为k-v元组的数组。然后按字段名称分组,并使用$addToSet来添加值。

db.collection.aggregate([
  {
    "$project": {
      _id: 0,
      arr: {
        "$objectToArray": "$$ROOT"
      }
    }
  },
  {
    "$unwind": "$arr"
  },
  {
    $match: {
      "arr.k": {
        $ne: "_id"
      }
    }
  },
  {
    $group: {
      _id: "$arr.k",
      values: {
        "$addToSet": "$arr.v"
      }
    }
  }
])

Mongo Playground

英文:

Assuming you don't know the full list of the fields beforehand, you need to use $objectToArray to convert the $$ROOT document into an array of k-v tuples. Then group by the field name and $addToSet the values.

db.collection.aggregate([
  {
    "$project": {
      _id: 0,
      arr: {
        "$objectToArray": "$$ROOT"
      }
    }
  },
  {
    "$unwind": "$arr"
  },
  {
    $match: {
      "arr.k": {
        $ne: "_id"
      }
    }
  },
  {
    $group: {
      _id: "$arr.k",
      values: {
        "$addToSet": "$arr.v"
      }
    }
  }
])

Mongo Playground

huangapple
  • 本文由 发表于 2023年2月19日 20:17:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/75500081.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定