【问题标题】:How to get data from collection in node js using mongoose如何使用 mongoose 从节点 js 中的集合中获取数据
【发布时间】:2017-05-03 09:24:49
【问题描述】:

我的 mongodb 中有 6 个不同的集合,这 5 个集合连接到一个连接,但我没有使用 ref,而是我得到了 5 个集合的 ID,然后将其保存到第 6 个集合即“列表”,这样我仍然有可以用作参考的公共字段

这是我的集合结构

list Collection
   var ListDoc = new mongoose.Schema({
       type_id        : {type: Schema.Types.ObjectId, required: true},
       detail_id      : {type: Schema.Types.ObjectId, required: true},
       address_id     : {type: Schema.Types.ObjectId, required: true},
       inquiries_id   : {type: Schema.Types.ObjectId, required: true},
       account_id     : {type: Schema.Types.ObjectId, required: true}
    });
    module.exports = mongoose.model('List', ListDoc);

Account Collection
    var accountDoc = new mongoose.Schema({
        email     : {type: String, unique: true, required: true},
        password  : {type: String, required: true}
    });
    module.exports = mongoose.model('Accounts', accountDoc );

Type Collection
    var TypeDoc = new mongoose.Schema({
        type   : {type: String, required: true},
        class  : {type: String, required: true},
    });
    module.exports = mongoose.model('Type', TypeDoc);

Detail Collection
    var DetailDoc = new mongoose.Schema({
        bedr         : {type: Number, required: true},
        diningr      : {type: Number, required: true},
        livingr      : {type: Number, required: true},
        kitchenr     : {type: Number, required: true}
        bathr        : {type: Number, required: true}
    });
    module.exports = mongoose.model('Detail', DetailDoc);

Address Collection
    var AddressDoc = new mongoose.Schema({
        city     : {type: String, required: true},
        brgy     : {type: String, required: true},
        street   : {type: String, required: true},
        bldgno   : {type: String, required: true},
        floorno  : {type: String, required: true},
        roomno   : {type: String, required: true}
    });
    module.exports = mongoose.model('Address', AddressDoc);

 Inquiries Collection
    var InquiriesDoc = new mongoose.Schema({
        inquiries    : {type: Number, required: true},
        views        : {type: Number, required: true},
    });
    module.exports = mongoose.model('Inquiries', InquiriesDoc);

注意:每个集合都有不同的 .js 文件

列表 Collection 将具有另一个 Collection 的 4 个 ID。

这就是我想要实现的目标

[ {
   "_id": "5907747e424c860f7495ad46",
   "account_id": "5908f3381cd9810ea8e2b517",
   "type": {
       "type" : "apartment",
       "class" : "middle"
      },
   "detail": {
       "bedr": 4,
       "diningr": 2,
       "livingr": 1,
       "kitchenr": 1,
       "bathr": 4
    },
   "address": {
       "city" : "lucena",
       "brgy" : "8",
       "street" : "rose",
       "bldgno" : "24",
       "floorno": "2",
       "roomno": "205"  
     },
  "inquiries": {
       "views" : 0,
       "inquires" : 0
      }
  },
  {
   "_id": "5907747e424c860f7495ad47",
   "account_id": "5908f3381cd9810ea8e2b517",
   "type_id": {
       "type" : "apartment",
       "class" : "middle"
             },
   "detail": {
       "bedr": 4,
       "diningr": 2,
       "livingr": 1,
       "kitchenr": 1,
       "bathr": 4
    },
   "address": {
       "city" : "lucena",
       "brgy" : "8",
       "street" : "rose",
       "bldgno" : "24",
       "floorno": "3",
       "roomno": "307"  
     },
   "inquiries": {
       "views" : 0,
       "inquires" : 0
       }
   }, ]

首先我获取列表集合中的所有数据,即 4 个集合的 ID,然后我尝试循环它以便我可以从其他集合中获取另一个数据

for(var loop =0 ; loop < list.length; loop++){
        var pt_id = list[loop].type_id;
        var pa_id = list[loop].address_id;
        var pd_id = list[loop].detail_id;
        var pi_id = list[loop].inquiries_id;
 }

我会在 for 循环中使用 async,然后使用 += 将其连接到“testresult”变量中

这是我的代码

var PL = require('../models/list');
var PT = require('../models/type');
var PA = require('../models/address');
var PD = require('../models/detail');
var PI = require('../models/inquiry');
var cryption    = require('../services/encrypt_decrypt');
var crypt = new cryption();
var async = require('async');


module.exports.read = function (request, response) {
var decryptedId = crypt.decrypt(request.decode.id);


var propertylistquery = PL.find({}).where('account_id').equals(decryptedId).select({"_id":0,"__v":0});

propertylistquery.exec(function (error, list) {
    if (error) {
        return response.status(500).send({success: false, error: error, message: 'Something went wrong.'});
    }
    if (!list) {
        return response.status(200).send({success: false, message: 'User not found in the database.'});
    }

    var testresult;
    for(var loop =0 ; loop < list.length; loop++){
        var pt_id = list[loop].type_id;
        var pa_id = list[loop].address_id;
        var pd_id = list[loop].detail_id;
        var pi_id = list[loop].inquiries_id;

        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // Getting the property type
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        var ptquery = PT.find({}).where('_id').equals(pt_id).select({"__v":0});

        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // Getting the property address
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        var paquery = PA.find({}).where('_id').equals(pa_id).select({"__v":0});

        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // Getting the property detail
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        var pdquery = PD.find({}).where('_id').equals(pd_id).select({"__v":0});

        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // Getting the propertyinquiry
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        var piquery = PI.find({}).where('_id').equals(pi_id).select({"__v":0});

        var resources = {
            Type        :   ptquery.exec.bind(ptquery),
            Address     :   paquery.exec.bind(paquery),
            Detail      :   pdquery.exec.bind(pdquery),
            Inquiry     :   piquery.exec.bind(piquery)
        };

        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // Asynchrozing the queries
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        async.parallel(resources, function (error, results){
            if (error) {
                response.status(500).send(error);
                return;
            }

            testresult += results;
            //console.log(results);
        });
    }


    console.log(testresult);
    response.json({success: true, data: list, message: 'Successfully fetched all property.'});
});

};

当我在 for 循环中记录“结果”变量时,它有一个数据 但是当我尝试记录“testresult”变量时,它是未定义的

我会怎么做才能得到我想要的输出?

【问题讨论】:

    标签: javascript node.js mongodb mongoose


    【解决方案1】:

    只需使用 $lookup 运算符从其他集合中进行连接,您可以在同一数据库中指定要执行连接的集合,并将结果存储在添加到的数组字段中输入文件。

    以下示例演示了 $lookup 的操作。要获得所需的输出,您需要在结果数组上应用 $arrayElemAt 运算符,这将返回由索引指定的数组中的子文档,在这种情况下为 0,因为它是唯一的元素 在数组中(一对一关系的结果将给出具有 $lookup 的单个元素数组):

    var PL = require('../models/list');
    var cryption    = require('../services/encrypt_decrypt');
    var crypt = new cryption();
    
    module.exports.read = function (request, response) {
        var decryptedId = crypt.decrypt(request.decode.id);
    
        PL.aggregate([
            { "$match": { "account_id": mongoose.Types.ObjectId(decryptedId) } },
            {
                "$lookup": {
                    "from": "pt", /* make sure the underlying collection name is correct */
                    "localField": "type_id",
                    "foreignField": "_id",
                    "as": "types"
                }
            },
            {
                "$lookup": {
                    "from": "pa", /* make sure the underlying collection name is correct */
                    "localField": "address_id",
                    "foreignField": "_id",
                    "as": "addresses"
                }
            },
            {
                "$lookup": {
                    "from": "pd", /* make sure the underlying collection name is correct */
                    "localField": "detail_id",
                    "foreignField": "_id",
                    "as": "details"
                }
            },
            {
                "$lookup": {
                    "from": "pi", /* make sure the underlying collection name is correct */
                    "localField": "inquiries_id",
                    "foreignField": "_id",
                    "as": "inquiries"
                }
            },
            {
                "$project": {
                    "account_id": 1,
                    "type": { "$arrayElemAt": ["$types", 0] },
                    "detail": { "$arrayElemAt": ["$addresses", 0] },
                    "address": { "$arrayElemAt": ["$details", 0] },
                    "inquiries": { "$arrayElemAt": ["$inquiries", 0] },
                }           
            }
        ]).exec(function (error, results){
            if (error) {
                response.status(500).send(error);           
            }
    
            console.log(results);
            response.json({
                success: true, 
                data: results, 
                message: 'Successfully fetched all property.'
            });
        });
    };
    

    【讨论】:

    • 感谢您的帮助,但是当我尝试您的代码时,它给出了一个空数组,然后当我删除 $match 中的 mongoose.Types.ObjectId() 因为 account_id 是一个字符串字段时,它给出了仅列表集合的 id 和 account_id。然后我尝试在外部字段中添加 mongoose.Types.ObjectId(),因为“_Id”是对象,它给出了这个错误“错误:传入的参数必须是 12 个字节的单个字符串或 24 个十六进制字符的字符串"
    • 您不能将mongoose.Types.ObjectId() 添加到$lookup 中的localFieldforeignFields 选项。您能否更新您的问题以显示所有相关模型的实际架构定义代码?
    • 谢谢您,chridam 先生,我更新了我的问题,我为每个集合都包含了我的架构
    • 谢谢chridam先生,经过几个小时的调试,终于解决了。我仍然使用上面的答案,问题不在于字段的类型,而在于它自己的集合名称。我制作的集合名称与存储在数据库中的集合名称不同,像这样。模型还是我自己做的:("Address") in Mongodb ("addresses")
    • 很高兴你设法解决了这个问题,我输入了一些 cmets /* make sure the underlying collection name is correct */ 我认为你在一开始就错过了,但现在你已经得到了正确的答案,向你致敬!
    猜你喜欢
    • 1970-01-01
    • 2019-09-18
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 2018-08-21
    • 2016-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多