簡體   English   中英

如何從嵌套數組 mongodb 中獲取單個匹配的文檔?

[英]How to fetch single matched document from nested array mongodb?

我在我的 MongoDB 文檔中嵌套了數組 object ,但是謂詞沒有按預期返回,在這種情況下我只想要匹配的文檔。

文件結構

{
"_id": {
    "$oid": "5fddb34848be35283c36955b"
},
"projectId": {
    "$oid": "5fddb30d48be35283c36955a"
},
"urls": [
    {
        "_id": {
            "$oid": "5fddb34848be35283c36955c"
        },
        "group": "User",
        "data": [
            {
                "option": {
                    "applyDifferentContentType": false,
                    "allowInjection": false
                },
                "_id": {
                    "$oid": "5fddad1e48be35283c369558"
                },
                "url": "/users/create",
                "method": "patch",
                "headers": {
                    "Content-Type": "multipart/form-data"
                }
            },
            {
                "option": {
                    "applyDifferentContentType": false,
                    "allowInjection": false
                },
                "_id": {
                    "$oid": "5fddad1e48be35283c369558"
                },
                "url": "/users/update",
                "method": "post",
                "headers": {
                    "Content-Type": "application/json"
                }
            },
            {
                "option": {
                    "applyDifferentContentType": false,
                    "allowInjection": false
                },
                "_id": {
                    "$oid": "5fddad1e48be35283c369558"
                },
                "url": "/users/delete",
                "method": "post",
                "headers": {
                    "Content-Type": "application/json"
                }
            }
        ]
    },
    {
        "_id": {
            "$oid": "5fddb34f48be35283c36955d"
        },
        "group": "Project",
        "data": [
            {
                "option": {
                    "applyDifferentContentType": true,
                    "allowInjection": false
                },
                "_id": {
                    "$oid": "5fddad1e48be35283c369558"
                },
                "url": "/project/create",
                "method": "post",
                "headers": {
                    "Content-Type": "application/json"
                }
            },
            {
                "option": {
                    "applyDifferentContentType": false,
                    "allowInjection": false
                },
                "_id": {
                    "$oid": "5fddad1e48be35283c369558"
                },
                "url": "/projects/update",
                "method": "post",
                "headers": {
                    "Content-Type": "application/url-encoded"
                }
            }
        ]
    },
    {
        "_id": {
            "$oid": "5fddb37d48be35283c36955e"
        },
        "group": "Contact",
        "data": [
            {
                "option": {
                    "applyDifferentContentType": false,
                    "allowInjection": false
                },
                "_id": {
                    "$oid": "5fddad1e48be35283c369558"
                },
                "url": "/contact/create",
                "method": "post",
                "headers": {
                    "Content-Type": "multipart/form-data"
                }
            }
        ]
    }
],
"__v": 0 }

獲取查詢

const result = await URLPayload.find({ 
  "projectId": projectId,
  "urls.data": {
    $elemMatch: {
      "_id": dataId
    }
  }
})
.lean();

projectId => 5fddb30d48be35283c36955a
dataId => 5fddad1e48be35283c369558

但是上面的謂詞沒有給出預期的結果。 如何從嵌套數組 object 中僅返回匹配的單個文檔?

我在我的 MongoDB 文檔中嵌套了數組 object ,但是謂詞沒有按預期返回,在這種情況下我只想要匹配的文檔。

我不習慣在 _id 元素中使用 $oid ,但這應該可以。

    const ids = {
        projectId: "5fddb30d48be35283c36955a",
        urlId: "5fddb34848be35283c36955c",
        dataId: "5fddad1e48be35283c369558"
    }

    await URLPayload.findOne({ "projectId.$oid": ids.projectId },
        {
            "$elemMatch": { "urls.$[url].data": { "_id.$oid": ids.dataId } }
        }, {
        "arrayFilters": [
            { "url._id.$oid": ids.urlId }
        ]
    }, (err, urlPayloadResult) => {
        if (err) {
            console.log(err)
        } else {
            console.log({ message: urlPayloadResult })
        }
    })

如果在您的情況下不起作用,只需刪除“.$oid”元素。

讓我知道這是否有效。

您可以使用聚合管道,

  • 使您必須使用mongoose.Types.ObjectIdprojectIddataId輸入字段字符串類型轉換為 object 類型
  • $match您的條件,
  • $project顯示所需文件
  • $reduce迭代urls數組的循環
  • $filter迭代urls.data數組的循環並過濾匹配_id
  • $first將從數組中返回 object,對於舊版本的 MongoDB,您可以使用$arrayElemAt而不是$first
const result = await URLPayload.aggregate([
  {
    $match: {
      projectId: mongoose.Types.ObjectId(projectId),
      "urls.data._id": mongoose.Types.ObjectId(dataId)
    }
  },
  {
    $project: {
      urlData: {
        $reduce: {
          input: "$urls",
          initialValue: {},
          in: {
            $first: {
              $filter: {
                input: "$$this.data",
                cond: { $eq: ["$$this._id", mongoose.Types.ObjectId(dataId)] }
              }
            }
          }
        }
      }
    }
  }
])

操場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM