在大文档中查找对象

时间:2017-06-30 16:48:26

标签: node.js mongodb mongoose

成为NoSQL / MongoDB的新手我想知道如何从潜在的大文档中获取特定对象。

我的项目集合中的文档如下所示:

{
    "_id" : ObjectId("5935a41f12f3fac949a5f925"),
    "project_id" : 13,
    "updated_at" : ISODate("2017-06-28T01:43:50.994Z"),
    "created_at" : ISODate("2017-06-05T18:34:07.150Z"),
    "owner" : ObjectId("591eea4439e1ce33b47e73c3"),
    "name" : "My demo project 1",
    "visibility" : 0,
    "uploaded_files" : [ 
        {
            "fieldname" : "sourceStrings",
            "originalname" : "Log_20-6-2017_19-03-24-626.txt",
            "encoding" : "7bit",
            "mimetype" : "text/plain",
            "_id" : ObjectId("5952deb44fb371d8bc00dd43")
        }]
}

而不只是一个"上传的文件对象"可能有数百个。我需要获取项目信息(如所有者,可见性,名称等),然后我想通过它_id获取uploaded_file对象。显然我可以迭代upload_files中的所有对象,但我认为这是性能明智可怕的。到目前为止我得到的是:

var projectId = req.params.projectId
var fileId = req.body.fileId
Project.findOne({ project_id: projectId }).populate('owner').then(project => {
        if (!project)
            return res.send(404, { error: "Couldn't find a project with this id"

        // Here I want to get the uploaded_file object

})

我的问题:

  1. 那么如何通过uploaded_files字段有效地从_id数组中获取单个对象?
  2. 我需要针对两种情况的行为,首先是我需要删除/修改上传的文件,或者我想获取所有信息。
  3. 我想要实现的目标是否有更好的数据库/文档设计?

1 个答案:

答案 0 :(得分:3)

您可以尝试使用“$ elemMatch”投影所需的对象,如下所示:

Project.findOne({ project_id: projectId } , 
{uploaded_files: {$elemMatch: {_id:  fileId}}})

这将返回仅包含所需文件对象的数组。

并且与如何更新它有关,您可以尝试以下方法:

Project.update({ project_id: projectId , 'uploaded_files._id' : 
fileId} , 
{$set : {"uploaded_files.$.originalname" : "new data"} }) 
//for example updating its "original name" filed and so on.

并注意“$”引用与查询匹配的第一个项目,由于依赖于查询中的“_id”属性,它应该只有一个。

最后从数组中删除特定元素,您可以尝试以下方法:

Project.update({ project_id: projectId }, 
{$pull : {"uploaded_files" : {_id:fileId}} })