【问题标题】:MongoDB: Distinct values from objects in subarrayMongoDB:子数组中的对象的不同值
【发布时间】:2019-05-13 06:40:32
【问题描述】:

我有一个这样结构的文档集合。例如:

{ 'observer': 'machine1', 
  'seen': [ 
     {'page1': ['/link1', '/link3']},
     {'page2': ['/link4', '/link1']},
}

{ 'observer': 'machine2', 
  'seen': [ 
     {'page3': ['/link2']},
     {'page1': ['/link5']},
}

我正在尝试获取数组中所有不同键和值的列表,按observer 分组。在理想的世界中,它看起来像:

{'machine1': ['/link1', '/link3', '/link4'], 'machine2': ['/link2', '/link5'] }

{'machine1': ['page1', 'page2'], 'machine2': ['page1', 'page3']}

我知道我可以使用 $aggregate 和 $group 来获取基于子列表的唯一值,但我不确定如何处理对象列表并获取它们的键和值。

【问题讨论】:

    标签: database mongodb mongodb-query aggregation-framework


    【解决方案1】:

    你可以使用下面的聚合

    db.collection.aggregate([
      { "$unwind": "$seen" },
      { "$addFields": {
        "seen": {
          "$objectToArray": "$seen"
        }
      }},
      { "$unwind": "$seen" },
      { "$unwind": "$seen.v" },
      { "$group": {
        "_id": "$observer",
        "links": { "$addToSet": "$seen.v" }
      }}
    ])
    

    MongoPlayground

    如果您同时需要pageslinks

    db.collection.aggregate([
      { "$unwind": "$seen" },
      { "$addFields": {
        "seen": {
          "$objectToArray": "$seen"
        }
      }},
      { "$unwind": "$seen" },
      { "$unwind": "$seen.v" },
      { "$facet": {
        "pages": [
          { "$group": {
            "_id": "$observer",
            "pages": { "$addToSet": "$seen.v" }
          }}
        ],
        "links": [
          { "$group": {
            "_id": "$observer",
            "links": { "$addToSet": "$seen.k" }
          }}
        ]
      }}
    ])
    

    MongoPlayground

    如果您需要更多改进

    db.collection.aggregate([
      { "$unwind": "$seen" },
      { "$addFields": {
        "seen": {
          "$objectToArray": "$seen"
        }
      }},
      { "$unwind": "$seen" },
      { "$unwind": "$seen.v" },
      { "$facet": {
        "pages": [
          { "$group": {
            "_id": "$observer",
            "pages": { "$addToSet": "$seen.v" }
          }}
        ],
        "links": [
          { "$group": {
            "_id": "$observer",
            "pages": { "$addToSet": "$seen.k" }
          }}
        ]
      }},
      { "$project": {
        "pages": {
          "$map": {
            "input": "$pages",
            "in": {
              "$let": {
                "vars": {
                  "links": {
                    "$arrayElemAt": [
                      "$links",
                      { "$indexOfArray": ["$links._id", "$$this._id"] }
                    ]
                  }
                },
                "in": {
                  "_id": "$$this._id",
                  "pages": "$$this.pages",
                  "links": "$$links.links"
                }
              }
            }
          }
        }
      }},
      { "$unwind": "$pages" },
      { "$replaceRoot": { "newRoot": "$pages" }}
    ])
    

    MongoPlayground

    【讨论】:

    • 谢谢!我对 Mongo 很陌生,所以我不太了解 unwind 和 facet 如何协同工作。这很有帮助。
    猜你喜欢
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 1970-01-01
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 2022-01-08
    相关资源
    最近更新 更多