从Mongo文档中获取所有阵列的值

发布于 2025-02-06 14:08:11 字数 566 浏览 2 评论 0原文

我有一个包含数组的文档的Mongo集合:

   { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
   { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
   { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
   { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
   { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }

我想获得一个包含所有不同值的单个数组,例如:

[blank“”,“ red”,“ red”,“ blue”]和dim_cm:[14,21,22.85, 30,10,15.25]

这是通过聚合管道的?

I have a mongo collection with documents containing arrays:

   { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
   { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
   { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
   { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
   { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }

I would like to get a single array containing all distinct values, such as:

tags: ["blank", "red", blue"] and dim_cm: [14,21,22.85,30,10,15.25]

Is this possible with an aggregation pipeline?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

您可以使用$ group$降低$ setIntersection

  1. $ group所有文档都创建一个数组每个键
  2. 使用$降低将每个数组弄平,并使用$ setIntersection使其成为集合。
db.collection.aggregate([
  {$group: {_id: null, tags: {$push: "$tags"}, dim_cm: {$push: "$dim_cm"}}},
  {
    $project: {
      _id: 0,
      tags: {
        $setIntersection: [
          {$reduce: {
              input: "$tags",
              initialValue: [],
              in: {$concatArrays: ["$value", "$this"]}
            }
          }
        ]
      },
      dim_cm: {
        $setIntersection: [
          {$reduce: {
              input: "$dim_cm",
              initialValue: [],
              in: {$concatArrays: ["$value", "$this"]}
            }
          }
        ]
      }
    }
  }
])

查看其在

工作

db.collection.aggregate([
  {$unwind: "$tags"},
  {
    $group: {
      _id: null,
      tags: {$addToSet: "$tags"},
      dim_cm: {$addToSet: "$dim_cm"
    }
  },
  {$unwind: "$dim_cm"},
  {$unwind: "$dim_cm"},
  {
    $group: {
      _id: null,
      tags: {$first: "$tags"},
      dim_cm: {$addToSet: "$dim_cm"}
    }
  }
])

方式/mongoplayground.net/p/udm4omq9lqv“ rel =“ nofollow noreferrer”> playground -undind

您可以将它们分为两个查询,这将更快:

db.collection.aggregate([
  {$unwind: "$tags"},
  {
    $group: {
      _id: null,
      tags: {$addToSet: "$tags"}
    }
  },
])

第三选项是:

db.collection.aggregate([
  {
    $project: {
      _id: 0,
      arr: {
        $concatArrays: [
          {$map: {input: "$tags", as: "item", in: {k: "tag",  v: "$item"}}},
          {$map: {input: "$dim_cm", as: "item", in: {k: "dim_cm", v: "$item"}}}
        ]
      }
    }
  },
  {$unwind: "$arr"},
  {
    $group: {
      _id: null,
      tags: {
        $addToSet: {$cond: [{$eq: ["$arr.k", "tag"]}, "$arr.v", "$REMOVE"]}
      },
      dim_cm: {
        $addToSet: {$cond: [{$eq: ["$arr.k", "dim_cm"]}, "$arr.v", "$REMOVE"]}
      }
    }
  }
])

Playground 3rd

You can use $group with $reduce and $setIntersection:

  1. $group all documents to create one array of arrays per key
  2. flatten each array with $reduce and make it a set using $setIntersection.
db.collection.aggregate([
  {$group: {_id: null, tags: {$push: "$tags"}, dim_cm: {$push: "$dim_cm"}}},
  {
    $project: {
      _id: 0,
      tags: {
        $setIntersection: [
          {$reduce: {
              input: "$tags",
              initialValue: [],
              in: {$concatArrays: ["$value", "$this"]}
            }
          }
        ]
      },
      dim_cm: {
        $setIntersection: [
          {$reduce: {
              input: "$dim_cm",
              initialValue: [],
              in: {$concatArrays: ["$value", "$this"]}
            }
          }
        ]
      }
    }
  }
])

See how it works on the playground example

Another way is:

db.collection.aggregate([
  {$unwind: "$tags"},
  {
    $group: {
      _id: null,
      tags: {$addToSet: "$tags"},
      dim_cm: {$addToSet: "$dim_cm"
    }
  },
  {$unwind: "$dim_cm"},
  {$unwind: "$dim_cm"},
  {
    $group: {
      _id: null,
      tags: {$first: "$tags"},
      dim_cm: {$addToSet: "$dim_cm"}
    }
  }
])

Playground - unwind

Which you can split into two queries which will be much faster:

db.collection.aggregate([
  {$unwind: "$tags"},
  {
    $group: {
      _id: null,
      tags: {$addToSet: "$tags"}
    }
  },
])

A 3rd option is:

db.collection.aggregate([
  {
    $project: {
      _id: 0,
      arr: {
        $concatArrays: [
          {$map: {input: "$tags", as: "item", in: {k: "tag",  v: "$item"}}},
          {$map: {input: "$dim_cm", as: "item", in: {k: "dim_cm", v: "$item"}}}
        ]
      }
    }
  },
  {$unwind: "$arr"},
  {
    $group: {
      _id: null,
      tags: {
        $addToSet: {$cond: [{$eq: ["$arr.k", "tag"]}, "$arr.v", "$REMOVE"]}
      },
      dim_cm: {
        $addToSet: {$cond: [{$eq: ["$arr.k", "dim_cm"]}, "$arr.v", "$REMOVE"]}
      }
    }
  }
])

Playground 3rd

写下不归期 2025-02-13 14:08:11

查询

  • 一个阵列中的两个阵列中
  • 在一个组中放在
  • ,请检查类型(字符串是否),然后放入正确的组

*此类类型是不同的,如果它们是相同类型的类型,我们可以做另一个技巧,例如将Pairs [[[TAG,CM] ...]首先是标签,第二个是CM或文档数组
如果您可以测试,则如果可以

aggregate(
[{"$project": {"tags-dim": {"$concatArrays": ["$tags", "$dim_cm"]}}},
 {"$unwind": "$tags-dim"},
 {"$group": 
   {"_id": null,
    "tags": 
     {"$addToSet": 
       {"$cond": 
         [{"$eq": [{"$type": "$tags-dim"}, "string"]}, "$tags-dim",
          "$REMOVE"]}},
    "dim_cm": 
     {"$addToSet": 
       {"$cond": 
         [{"$eq": [{"$type": "$tags-dim"}, "string"]}, "$REMOVE",
          "$tags-dim"]}}}}])

Query

  • put both in one array
  • unwind
  • at group time check the type(string or not) and put to the right group

*here types are different, in case they were the same type, we can do another trick like put the in an array of pairs [[tag,cm] ...] where first would be the tag and the second would be the cm, or array of documents
For perfomance if you test it send how it went if you can

Playmongo

aggregate(
[{"$project": {"tags-dim": {"$concatArrays": ["$tags", "$dim_cm"]}}},
 {"$unwind": "$tags-dim"},
 {"$group": 
   {"_id": null,
    "tags": 
     {"$addToSet": 
       {"$cond": 
         [{"$eq": [{"$type": "$tags-dim"}, "string"]}, "$tags-dim",
          "$REMOVE"]}},
    "dim_cm": 
     {"$addToSet": 
       {"$cond": 
         [{"$eq": [{"$type": "$tags-dim"}, "string"]}, "$REMOVE",
          "$tags-dim"]}}}}])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文