首页 > 解决方案 > 获取不同的嵌入文档

问题描述

我有一个包含这样的元素的集合:

{
    "_id": {
        "$oid": "56d61033a378eccde8a8354f"
    },
    "id": "10021-2015-ENFO",
    "certificate_number": 9278806,
    "business_name": "ATLIXCO DELI GROCERY INC.",
    "date": "Feb 20 2015",
    "result": "No Violation Issued",
    "sector": "Cigarette Retail Dealer - 127",
    "address": {
        "city": "RIDGEWOOD",
        "zip": 11385,
        "street": "MENAHAN ST",
        "number": 1712
    }
}

我想要的是_id为每个address. 这是一次性操作,我这样做是为了研究/测试目的。

我认为我可以将任务分为以下步骤:

我选择这样的文件:

db.ci.find({}, {"address":1, "_id":0});

但我无法使用Distinct函数或foreach. 我也尝试使用aggregate,但没有成功。

谁能给我一些提示?

我正在使用 Ubuntu 20.04、mongodb 4.2.7 和带有mongodb 扩展的代码。

标签: mongodb

解决方案


您可以在单个聚合中获得一个唯一整数,方法是使用$facet保留原始文档,同时使用$addToSet获取唯一地址列表,并将$indexOfArray值分配给每个文档:

db.collection.aggregate([
  {$facet: {
      docs: [{$match: {}}],
      addresses: [
        {$group: {
            _id: null,
            address: {$addToSet: "$address"}
        }}
      ]
  }},
  {$unwind: "$docs"},
  {$unwind: "$addresses"},
  {$addFields: {
      "address.id": {
        $indexOfArray: [
          "$addresses.address",
          "$docs.address"
        ]
      }
  }},
  {$replaceRoot:{newRoot:"$docs"}},
  {$out:"new_collection"}
])

操场

如果您更喜欢 ObjectId,那么您有正确的想法,将唯一地址输出到临时集合的一个聚合,因此每个都自动分配一个 _id,然后第二个聚合将这些 _id 值嵌入到原始文档中。对于此示例,我收集了原始文档的 _id 以简化以后的查找。

db.collection.aggregate([
  {$group:{
       _id:"$address",
       ids:{$push:"$_id"}
  }},
  {$project:{
       address:"$_id",
       ids:1,
       _id:0
  }},
  {$out: "temp_address_collection"}
])

操场

db.collection.aggregate([
  {$lookup:{
      from:"temp_address_collection",
      localField:"_id",
      foreignField:"ids",
      as: "matched"
  }},
  {$addFields:{matched:{$arrayElemAt:["$matched",0]}}},
  {$addFields:{"$address.id": "$matched._id"}},
  {$project:{matched:0}},
  {$out:"new_collection"}
])

操场


推荐阅读