【问题标题】:Recursive checking for folder name per aggregate?递归检查每个聚合的文件夹名称?
【发布时间】:2021-11-10 00:23:43
【问题描述】:

我有以下示例文档:(parent_id: null 表示文件/文件夹位于根目录)


{"_id":"a", "name":"Pictures", "parent_id": null, "type": "folder"}
{"_id":"d", "name":"Paris", "parent_id":"b", "type": "folder"}
{"_id":"c", "name":"New Folder", "parent_id": null, "type": "folder"}
{"_id":"b", "name":"Vacation 2020", "parent_id":"a", "type": "folder"}
{"_id":"e", "name":"Videos", "parent_id": null, "type": "folder"}
{"_id":"f", "name": "Paris", "parent_id": null, "type": "folder"}

我有一个包含值的数组:(与Pictures/Vacation 2020/ParisPictures > Vacation 2020 > Paris 作为路径基本相同)

["Pictures", "Vacation 2020", "Paris"]

我想看看最终结果:

{"_id":"a", "name":"Pictures", "parent_id": null, "type": "folder"}
{"_id":"b", "name":"Vacation 2020", "parent_id":"a", "type": "folder"}
{"_id":"d", "name":"Paris", "parent_id":"b", "type": "folder"}

有没有办法,也许是在聚合状态,它首先搜索

// First Folder
"name": "Pictures"
"parent_id": null

返回给{"_id":"a", "name":"Pictures", "parent_id": null, "type": "folder"} 然后它会搜索下一个子文件夹:

// Second Folder
"name": "Vacation 2020"
"parent_id": "a"

这将导致返回到{"_id":"b", "name":"Vacation 2020", "parent_id":"a", "type": "folder"}。然后使用以下最终命令:

// Third Folder
"name": "Paris"
"parent_id": "b"

然后将所有找到的文档(从最终结果)返回给我?

我正在考虑将 for 循环与 findOne 一起使用,但它听起来不像使用聚合函数那样有效。

有人有想法吗?那很好啊!谢谢!

DarkLordCoder

附:每个文件夹在相同的 parent_id 上都有唯一的名称。因此,您可以拥有 2 个名为“Paris”的文件夹,但它具有不同的 parent_id(因为它们位于不同的文件夹中)。

【问题讨论】:

    标签: node.js json mongodb aggregate


    【解决方案1】:

    我发现根据给定的要求,完成任务的最简单方法是首先找到数组中的最后一项。这样做更容易获取父母,因为我们有 parent_id 属性。

    流程是这样的:

    1. 获取数组 (myArray) 中的最后一个元素
    2. 在文档数组 (foundIem) 中找到该项目
    3. 将项目添加到数组中(在 addItemFindParent 函数中)
    4. 如果 parent_id 存在,则获取项目,然后递归调用 addItemFindParent 函数

    更新

    const documents = [
      { _id: 'a', name: 'Pictures', parent_id: null, type: 'folder' },
      { _id: 'b', name: 'Pictures', parent_id: 'g', type: 'folder' },
      { _id: 'c', name: 'Vacation 2020', parent_id: 'a', type: 'folder' },
      { _id: 'd', name: 'Vacation 2020', parent_id: 'b', type: 'folder' },
      { _id: 'e', name: 'Paris', parent_id: 'c', type: 'folder' },
      { _id: 'f', name: 'Paris', parent_id: 'd', type: 'folder' },
      { _id: 'g', name: 'Old Stuff', parent_id: null, type: 'folder' }
    ]
    
    const myArray = ['Pictures', 'Vacation 2020', 'Paris']
    
    const items = myArray.reduce((pv, cv) => {
      const foundItems = documents.filter(doc => doc.name === cv)
      if (foundItems.length) {
        pv.push(foundItems)
        return pv
      } else {
        throw new Error(`No items found for ${cv}`)
      }
    }, [])
    
    const findItems = items.reduce((parentPV, parentCV, parentIndex) => {
      if (parentIndex === 0) {
        parentCV = parentCV.filter(doc => !doc.parent_id)
        parentPV.push(parentCV)
        return parentPV
      } else {
        parentCV = parentCV.reduce((childPV, childCV, childIndex) => {
          const foundParent = parentPV.find(doc => doc._id === childCV.parent_id)
          if (foundParent) {
            childPV.push(childCV)
          }
          return childPV
        })
        parentPV.push(parentCV)
        return parentPV
      }
    }, [])
    
    console.log(findItems)
    
    

    【讨论】:

    • 我使用 parent_id 的原因是为了避免名称冲突。参见示例“巴黎”。我们在这里有 2 个巴黎,但在不同的位置。一个 "Paris" 有 "parent_id": null 因为它在根目录中。其他“巴黎”位于“图片”>“假期 2020”>“巴黎”。 “Paris”中的“parent_id”:“b”表示父文件夹是“Vacation 2020”,其_id:“b”。而“2020 年假期”的 parent_id 是“a”,即文件夹“图片”等等。
    • 好的,它现在应该适合你了。我刚刚添加了一个递归函数,如果有 parent_id,它会调用自己。
    • 虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的答案添加解释并说明适用的限制和假设。
    • 我实际上希望使用聚合函数,因为这个函数可能非常慢,尤其是。如果您使用的是 MongoDB Atlas 等第三方服务。否则 - 这是一个很好的解决方案,我也有类似的想法!谢谢!
    • 另外这个真的解决不了。因为在不同的父文件夹(每个 parent_id)可以有多个“巴黎”文件夹。这意味着可以有 4 个“Paris”文件夹,但具有不同的 parent_id。
    猜你喜欢
    • 2019-05-28
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 2014-05-06
    • 2020-08-20
    相关资源
    最近更新 更多