当前位置: 首页 > 知识库问答 >
问题:

查找符合条件的所有子文档

梁俊友
2023-03-14

我想只从我的两个对象数组file_historyuploaded_files中得到那些符合标准的子文档。即使我已经找到了这个stackoverflow答案#2(根据标准查找猫鼬子文档),它对我来说并不像期望的那样工作,或者我错过了一些东西。

var projectId = req.params.projectId
var uploadId = req.body.uploadId

let populateQuery = [
    {path: 'owner'},
    {path: 'uploaded_files.file', match: {upload_id: uploadId}},
    {path: 'file_history.file', match: {upload_id: uploadId}}
]

Project.findOne({ project_id: projectId }).populate(populateQuery).then(project => {
    console.log(project)
})

我的文档如下所示:

{
    "_id" : ObjectId("5935a41f12f3fac949a5f925"),
    "project_id" : 13,
    "updated_at" : ISODate("2017-07-05T21:45:46.754Z"),
    "created_at" : ISODate("2017-06-05T18:34:07.150Z"),
    "owner" : ObjectId("591eea4439e1ce33b47e73c3"),
    "name" : "RDemo project",
    "uploaded_files" : [ 
        {
            "display_name" : "Log_28-6-2017_14-17-53-562.txt",
            "file" : ObjectId("595c4c4f3ae2470700ea07e2"),
            "upload_id" : ObjectId("595c0f7ea1d20247285be5f5"),
            "created_at" : ISODate("2017-07-05T02:17:51.000Z")
        }, 
        {
            "display_name" : "Coon.png",
            "file" : ObjectId("595c4c553ae2470700ea07e4"),
            "upload_id" : ObjectId("595c4c553ae2470700ea07e5"),
            "created_at" : ISODate("2017-07-05T02:17:57.000Z")
        }
    ],
    "file_history" : [ 
        {
            "display_name" : "account working.txt",
            "file" : ObjectId("595c0f7ea1d20247285be5f4"),
            "upload_id" : ObjectId("595c0f7ea1d20247285be5f5"),
            "created_at" : ISODate("2017-07-04T21:58:22.000Z")
        }, 
        {
            "display_name" : "Log_28-6-2017_14-17-53-562.txt",
            "file" : ObjectId("595c4c4f3ae2470700ea07e2"),
            "upload_id" : ObjectId("595c0f7ea1d20247285be5f5"),
            "created_at" : ISODate("2017-07-05T02:17:51.000Z")
        }
    ]
}

它将在文件\u历史上传的\u文件中打印项目及其所有子文档。但是,我只想获取与给定上载id匹配的子文档。我做错了什么?

编辑:这个问题是指用猫鼬来解决它。我不能在Mongoose中使用这个问题的集合语句(只检索MongoDB集合中对象数组中的查询元素),因为它返回了一个空数组,但是我能够通过MongoDB运行它,它确实返回了所需的结果。这是我试过的代码:

    let projectId = req.params.projectId // Project ID is an integer and no objectId
    let uploadId = new mongoose.Types.ObjectId(req.body.uploadId)
    console.log(`ProjectID: ${projectId}, uploadId: ${uploadId}, params: ${req.body.uploadId}`)

    let populateQuery = [
        {path: 'owner'},
        {path: 'uploaded_files.file'},
        {path: 'file_history.file'}
    ]

    Project.aggregate(
        {$match: {"project_id": projectId}},
        {$project: {
            uploaded_files: {$filter: {
                    input: '$uploaded_files',
                    as: 'uploadedFile',
                    cond: {$eq: ['$$uploadedFile.upload_id', uploadId]}
                }}
            }
        }
    ).then(project => {
        console.log(project)
})

console.log返回:ProjectID:13,uploadId:595c0f7ea1d20247285be5f5,params:595c0f7ea1d20247285be5f5哪个正确(ID存在)

共有1个答案

陈富
2023-03-14

你做了一件可怕的错事,不清楚那是什么。因此,向你展示的最好方式就是以身作则。

还要注意的是,$filter甚至不需要进行“单一匹配”,标准位置投影只需在此处执行即可:

const async = require('async'),
      mongoose = require('mongoose'),
      Schema = mongoose.Schema,
      ObjectId = require('mongodb').ObjectID

mongoose.set('debug',true)
mongoose.Promise = global.Promise;

mongoose.connect('mongodb://localhost/test');

const doc =
{
    "_id" : ObjectId("5935a41f12f3fac949a5f925"),
    "project_id" : 13,
    "updated_at" : new Date("2017-07-05T21:45:46.754Z"),
    "created_at" : new Date("2017-06-05T18:34:07.150Z"),
    "owner" : ObjectId("591eea4439e1ce33b47e73c3"),
    "name" : "RDemo project",
    "uploaded_files" : [
        {
            "display_name" : "Log_28-6-2017_14-17-53-562.txt",
            "file" : ObjectId("595c4c4f3ae2470700ea07e2"),
            "upload_id" : ObjectId("595c0f7ea1d20247285be5f5"),
            "created_at" : new Date("2017-07-05T02:17:51.000Z")
        },
        {
            "display_name" : "Coon.png",
            "file" : ObjectId("595c4c553ae2470700ea07e4"),
            "upload_id" : ObjectId("595c4c553ae2470700ea07e5"),
            "created_at" : new Date("2017-07-05T02:17:57.000Z")
        }
    ],
    "file_history" : [
        {
            "display_name" : "account working.txt",
            "file" : ObjectId("595c0f7ea1d20247285be5f4"),
            "upload_id" : ObjectId("595c0f7ea1d20247285be5f5"),
            "created_at" : new Date("2017-07-04T21:58:22.000Z")
        },
        {
            "display_name" : "Log_28-6-2017_14-17-53-562.txt",
            "file" : ObjectId("595c4c4f3ae2470700ea07e2"),
            "upload_id" : ObjectId("595c0f7ea1d20247285be5f5"),
            "created_at" : new Date("2017-07-05T02:17:51.000Z")
        },
        {
            "display_name" : "Coon.png",
            "file" : ObjectId("595c4c553ae2470700ea07e4"),
            "upload_id" : ObjectId("595c4c553ae2470700ea07e5"),
            "created_at" : new Date("2017-07-05T02:17:57.000Z")
        },
        {
            "display_name" : "Coon.png",
            "file" : ObjectId("595c4c553ae2470700ea07e4"),
            "upload_id" : ObjectId("595c4c553ae2470700ea07e5"),
            "created_at" : new Date("2017-07-05T02:17:57.000Z")
        }
    ]
};

const Test = mongoose.model('Test', new Schema({}, { strict: false }) );

function log(data) {
  console.log(JSON.stringify(data, undefined, 2))
}

async.series(
  [
    // Clean data
    (callback) =>
      async.each(mongoose.models,(model,callback) =>
        model.remove({},callback),callback),

    // Insert data
    (callback) => Test.insertMany(doc,callback),

    // Correct usage of $filter
    (callback) =>
      Test.aggregate(
        [
          { "$match": { "project_id": 13 } },
          { "$addFields": {
            "uploaded_files": {
              "$filter": {
                "input": "$uploaded_files",
                "as": "f",
                "cond": {
                  "$eq": [
                    "$$f.upload_id", ObjectId("595c0f7ea1d20247285be5f5")
                  ]
                }
              }
            },
            "file_history": {
              "$filter": {
                "input": "$file_history",
                "as": "f",
                "cond": {
                  "$eq": [
                    "$$f.upload_id", ObjectId("595c0f7ea1d20247285be5f5")
                  ]
                }
              }
            }

          }}
        ],
        (err,results) => {
          if (err) callback(err);
          log(results);
          callback();
        }
      ),

      // Just a normal positional project for 1 match
      (callback) => Test.findOne(
        { "uploaded_files.upload_id": ObjectId("595c0f7ea1d20247285be5f5") },
        { "uploaded_files.$": 1 },
        (err,result) => {
          if (err) callback(err);
          log(result);
          callback();
        }
      )

  ],
  (err) => {
    if (err) throw err;
    mongoose.disconnect();
  }
)

产生所需的输出:

[
  {
    "_id": "5935a41f12f3fac949a5f925",
    "__v": 0,
    "project_id": 13,
    "updated_at": "2017-07-05T21:45:46.754Z",
    "created_at": "2017-06-05T18:34:07.150Z",
    "owner": "591eea4439e1ce33b47e73c3",
    "name": "RDemo project",
    "uploaded_files": [
      {
        "created_at": "2017-07-05T02:17:51.000Z",
        "upload_id": "595c0f7ea1d20247285be5f5",
        "file": "595c4c4f3ae2470700ea07e2",
        "display_name": "Log_28-6-2017_14-17-53-562.txt"
      }
    ],
    "file_history": [
      {
        "created_at": "2017-07-04T21:58:22.000Z",
        "upload_id": "595c0f7ea1d20247285be5f5",
        "file": "595c0f7ea1d20247285be5f4",
        "display_name": "account working.txt"
      },
      {
        "created_at": "2017-07-05T02:17:51.000Z",
        "upload_id": "595c0f7ea1d20247285be5f5",
        "file": "595c4c4f3ae2470700ea07e2",
        "display_name": "Log_28-6-2017_14-17-53-562.txt"
      }
    ]
  }
]
Mongoose: tests.findOne({ 'uploaded_files.upload_id': ObjectId("595c0f7ea1d20247285be5f5") }, { fields: { 'uploaded_files.$': 1 } })
{
  "_id": "5935a41f12f3fac949a5f925",
  "uploaded_files": [
    {
      "display_name": "Log_28-6-2017_14-17-53-562.txt",
      "file": "595c4c4f3ae2470700ea07e2",
      "upload_id": "595c0f7ea1d20247285be5f5",
      "created_at": "2017-07-05T02:17:51.000Z"
    }
  ]
}
 类似资料:
  • 问题内容: 我正在尝试使用操作数AND一起查询集合。我有外壳版本工作: 我找不到Java等效项(使用本机驱动程序)。我已经尝试了各种方法,但这是我最近的尝试: 任何想法有什么问题吗? 问题答案:

  • 我的简化模式如下所示: 我想找到所有叫艾伦的人。我看了这个非常相似的问题,但它发现的是团队,而不是人。我想这里也是。即使我没有persons集合,是否有返回persons的查询? 我想我可以使用引用的技术找到团队,然后撤出他们的人员。我猜是这样的: 但是还有更直接的方法,对吗?

  • 问题内容: 我刚刚陷入这个问题。我有两种猫鼬模式: 问题是,如何从每个父文档中获取所有子文档(在这种情况下为对象)?假设我有一些数据: 我想通过一个查询来检索所有18岁以上的孩子。每个答案将不胜感激,谢谢! 问题答案: 您可以在最新的MongoDB版本中用作查询投影运算符。从mongo shell: 这会从数组中过滤掉较小的儿童文档: 如您所见,子代仍在其父文档中分组。MongoDB查询返回集合中

  • 我使用的是android(SQL)中的Room database,我有一个表,它将日期作为一列存储为2000-01-31格式的字符串。我想获得表中的所有条目,根据它们各自的月份。我想用 但这样,我将不得不为每个月编写单独的查询。我想获得的条目按月,并显示在我的android应用程序。

  • 如何根据对象数组的条件获取所有索引?我已经尝试了下面的代码,但是它只返回第一次出现的代码。

  • 问题内容: 我有以下数据: 对于每组记录(按ParentID分组),我想查找所有没有包含“ A”作为数据值的记录的组。 由于第1组和第6组确实包含至少一个以“ A”作为数据值的记录,因此我不希望看到它们。我只想查看记录4和5(它们是组4的一部分),因为该组中没有记录带有“ A”。 任何帮助是极大的赞赏! 问题答案: 如果表很大,建议建立索引。