【问题标题】:Mongoose: Populating a nested array of idsMongoose:填充嵌套的 id 数组
【发布时间】:2019-12-06 22:24:24
【问题描述】:

我一直在网上寻找解决方案,但似乎找不到我的问题的答案。 Here's a very similar case, 但由于某种原因,我的文档仍然没有被填充。 以下是架构:

客户架构:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var customerSchema = new Schema({
  _id: {type: Schema.Types.ObjectId},
  auditTrail: {type: Object},
  thirdParty: [{type: Schema.Types.ObjectId, ref: 'Thirdparty'}],
  docRefs: {type: Object},
  salesRep: {type: Array},
  commentsArr: {type: Array}
});

module.exports = mongoose.model('Customer', customerSchema);

第三方的:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var thirdPartySchema = new Schema({
  _id: {type: Schema.Types.ObjectId},
  type: {type: String},
  name: {type: String},
  vat: {type: String},
  corpoPhone: {type: String},
  corpoMail: {type: String},
  corpoWeb: {type: String},
  activityNumber: {type: String},
  addresses: {type: Array},
  contacts: [{type: Schema.Types.ObjectId, ref: 'Contact'}], // <-- ARRAY OF ObjectIds /!\
});

module.exports = mongoose.model('Thirdparty', thirdPartySchema);

和联系人的:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var contactSchema = new Schema({
  _id: {type: Schema.Types.ObjectId},
  title: {type: String},
  role: {type: String},
  firstName: {type: String},
  lastName: {type: String},
  phone: {type: String},
  mobile: {type: String},
  email: {type: String}
});

module.exports = mongoose.model('Contact', contactSchema);

这是我的电话:

Customer
    .find()
    .populate({
      path: 'thirdParty',
      populate: { path: 'contacts', model: 'Contact' }
    })
    .then(
    //... Do something
  )

如果第三方在客户中完全填充,则联系人绝对不会... 这是“响应”的日志:

我做错了什么?

提前致谢!

【问题讨论】:

    标签: mongoose mongoose-schema mongoose-populate


    【解决方案1】:

    Array 内的Array 不能直接工作。您需要$unwind进行进一步操作和两个级别的$group

    冗长,但这是您实现要求的方式。

    db.getCollection('Customer').aggregate([
      {$unwind: "$thirdParty"},
      {$lookup: {from: 'Thirdparty', localField: 'thirdParty', foreignField: '_id', as: 'thirdParty'}},
      {$unwind: "$thirdParty"},
      {$unwind: "$thirdParty.contacts"},
      {$lookup: {from: 'Contact', localField: 'thirdParty.contacts', foreignField: '_id', as: 'thirdParty.contacts'}},
      {$unwind: "$thirdParty.contacts"},
      { $group: {
            _id: {
              custid: "$_id",
              tId: "$thirdParty._id"
            },
            auditTrail: {$first: "$auditTrail"},
            docRefs: {$first: "$docRefs"},
            salesRep: {$first: "$salesRep"},
            commentsArr: {$first: "$commentsArr"},
            contactsArr: {$push: "$thirdParty.contacts"},
            thirdParty: {$first:"$thirdParty"}
      }},
      {$group: {
        _id: "$_id.custid",
        auditTrail: {$first: "$auditTrail"},
        docRefs: {$first: "$docRefs"},
        salesRep: {$first: "$salesRep"},
        commentsArr: {$first: "$commentsArr"},
        thirdParty: {$push: {
            "_id": "$thirdParty._id",
            "type" : "$thirdParty.type",
            "name" : "$thirdParty.name",
            "vat" : "$thirdParty.vat",
            "corpoPhone" : "$thirdParty.corpoPhone",
            "corpoMail" : "$thirdParty.corpoMail",
            "corpoWeb" : "$thirdParty.corpoWeb",
            "activityNumber" :"$thirdParty.activityNumber",
            "addresses" : "$thirdPartyaddresses",
            "contacts": "$contactsArr"
        }},
      }}
    ])
    

    下面是输出:

    {
      "_id" : ObjectId("5d3f0a70d4a630e6a5499d3a"),
      "auditTrail" : {},
      "docRefs" : {},
      "salesRep" : [],
      "commentsArr" : [],
      "thirdParty" : [{
        "_id" : ObjectId("5d3fe4ddd4a630e6a5499d3b"),
        "type" : "type2",
        "name" : "type2",
        "vat" : "type2",
        "corpoPhone" : "type2",
        "corpoMail" : "type2",
        "corpoWeb" : "type2",
        "activityNumber" : "type2",
        "contacts" : [{
          "_id" : ObjectId("5d3f09edd4a630e6a5499d38"),
          "title" : "title1",
          "role" : "role1",
          "firstName" : "firstname1",
          "lastName" : "lastname1",
          "phone" : "phone1",
          "mobile" : "mobile1",
          "email" : "email1"
        }, {
          "_id" : ObjectId("5d3fe547d4a630e6a5499d3d"),
          "title" : "title2",
          "role" : "role2",
          "firstName" : "firstname2",
          "lastName" : "lastname2",
          "phone" : "phone2",
          "mobile" : "mobile2",
          "email" : "email2"
        }]
      }, {
        "_id" : ObjectId("5d3f0a36d4a630e6a5499d39"),
        "type" : "type1",
        "name" : "type1",
        "vat" : "type1",
        "corpoPhone" : "type1",
        "corpoMail" : "type1",
        "corpoWeb" : "type1",
        "activityNumber" : "type1",
        "contacts" : [ {
          "_id" : ObjectId("5d3f09edd4a630e6a5499d38"),
          "title" : "title1",
          "role" : "role1",
          "firstName" : "firstname1",
          "lastName" : "lastname1",
          "phone" : "phone1",
          "mobile" : "mobile1",
          "email" : "email1"
        }]
      }]
    }
    

    【讨论】:

    • 嘿哈迪克,感谢您的回答。但是,虽然 Mongoose 中有一个聚合函数,但我觉得您使用的语法是直接来自 MongoDB 的 API 而不是 Mongoose,对吗?
    • 对,你可以在使用mongoose聚合函数获取记录的同时使用这个聚合。
    • 好吧...让我试试。正如你所说,这似乎有点“冗长”,猫鼬的文件似乎暗示有解决方案mongoosejs.com/docs/populate.html#deep-populate...
    • 您的解决方案没有错误,但我得到一个完全空的文档数组:{ "message": "Customer successfully fetched", "customers": [ ] }
    • 猫鼬搞定了!我将发布解决方案。不管怎么说,多谢拉! :)
    【解决方案2】:

    知道了!我错过了模型中的导入语句:

    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    var Contact = require('./contact'); // <--- THIS LINE RIGHT HERE
    
    var thirdPartySchema = new Schema({
      _id: {type: Schema.Types.ObjectId},
      type: {type: String},
      name: {type: String},
      vat: {type: String},
      corpoPhone: {type: String},
      corpoMail: {type: String},
      corpoWeb: {type: String},
      activityNumber: {type: String},
      addresses: {type: Array},
      contacts: [{type: Schema.Types.ObjectId, ref: 'Contact'}],
    });
    
    module.exports = mongoose.model('Thirdparty', thirdPartySchema);
    

    请求看起来像:

    Customer
        .find()
        .populate({
          path: 'thirdParty',
          populate: { path: 'contacts', model: 'Contact' }
        })
        .then(
        documents => {
          res.status(200).json({
            message: 'Customer successfully fetched',
            customers: documents
          });
        }
      ).catch(err => res.status(404).json({message: 'No customer found!', error: err}));
    });
    

    现在我的“对象”得到了正确填充:

    {
      "message": "Customer successfully fetched",
      "customers": [
        {
          "thirdParty": [
            {
              "addresses": [
                {
                  "street": "AVENIDA ESTADOS UNIDOS, 141",
                  "streetcomp": "",
                  "streetcomp2": "",
                  "city": "SAN BARTOLOME DE TIRAJANA ",
                  "cp": "35290",
                  "state": "PALMAS (LAS)",
                  "country": "spain",
                  "main": true
                },
                {
                  "street": "OTRA DIRECCION DUMMY",
                  "streetcomp": "",
                  "streetcomp2": "",
                  "city": "MADRID",
                  "state": "MADRID",
                  "country": "spain",
                  "main": false
                }
              ],
              "contacts": [
                {
                  "_id": "5cf0f6f2a3e9cf847c5861af",
                  "title": "Mrs.",
                  "role": "CFO",
                  "firstName": "John",
                  "lastName": "Doe",
                  "phone": "912345654",
                  "mobile": "673369900",
                  "thirdParty_id": "5cf0f6d0a3e9cf847c5861aa",
                  "addresses": [
                    {
                      "street": "AVENIDA ESTADOS UNIDOS , 141",
                      "streetcomp1": "TUNTE",
                      "streetcomp2": "",
                      "cp": "35290",
                      "city": "SAN BARTOLOME DE TIRAJANA ",
                      "state": "PALMAS (LAS)"
                    }
                  ],
                  "email": "jdoe@ketchup.com",
                  "auditTrail": {
                    "creation": {
                      "user_id": "1",
                      "creationDate": "1559213796974"
                    },
                    "modification": [
                      {
                        "user_id": "1",
                        "modifDate": "1559213833358"
                      }
                    ]
                  }
                }
              ],
              "_id": "5cf0f6d0a3e9cf847c5861aa",
              "type": "customer",
              "name": "ketchup",
              "vat": "B87451084",
              "corpoPhone": "918388544",
              "corpoMail": "obras@ferrometal.net",
              "corpoWeb": "http://ferrometalcimentaciones.es/",
              "activityNumber": "5630"
            }
          ],
          "salesRep": [
            {
              "user_id": "USER_ID to be defined",
              "dateBegin": "1559212324146",
              "active": true
            },
            {
              "user_id": "USER_ID to be defined",
              "dateBegin": "1559212324146",
              "active": false
            }
          ],
          "commentsArr": [
            {
              "user_id": "USER_ID to be changed to name",
              "comment": "this is a great customer!"
            },
            {
              "user_id": "USER_ID to be changed to name",
              "comment": "This is a test"
            }
          ],
          "_id": "5cf0f704a3e9cf847c5861b2",
          "auditTrail": {
            "modifications": [
              {
                "modificationDate": "1559211664284",
                "user_id": "A123"
              }
            ],
            "creation": {
              "creationDate": "1559211664284",
              "user_id": "A123"
            }
          },
          "docRefs": {
            "fs": [
              {
                "name": "mod 200 2018",
                "comment": "should be approved",
                "url": "www.google.com",
                "uploadDate": "1559212324146",
                "originalName": "mod200-2018.pdf",
                "mime": "pdf",
                "type": "fs",
                "typeName": "Financial Statements"
              }
            ],
            "id": [
              {
                "name": "Jose-Pedro",
                "comment": "ID Valido",
                "url": "/somehwere/else",
                "uploadDate": "1559212324146",
                "originalName": "id-jp.pdf",
                "mime": "pdf",
                "type": "id",
                "typeName": "Identification Document"
              }
            ],
            "ad": [
    
            ],
            "cd": [
    
            ],
            "pd": [
    
            ],
            "od": [
    
            ]
          },
          "active": true
        },
        {
          "thirdParty": [
            {
              "addresses": [
                {
                  "street": "CALLE MORGAN , 2 - BJ 2 B",
                  "streetcomp": "",
                  "streetcomp2": "",
                  "city": "BILBAO",
                  "cp": "48014",
                  "state": "BIZKAIA",
                  "country": "spain",
                  "main": true
                }
              ],
              "contacts": [
                {
                  "_id": "5cf0f6f2a3e9cf847c5861af",
                  "title": "Mrs.",
                  "role": "CFO",
                  "firstName": "John",
                  "lastName": "Doe",
                  "phone": "912345654",
                  "mobile": "673369900",
                  "thirdParty_id": "5cf0f6d0a3e9cf847c5861aa",
                  "addresses": [
                    {
                      "street": "AVENIDA ESTADOS UNIDOS , 141",
                      "streetcomp1": "TUNTE",
                      "streetcomp2": "",
                      "cp": "35290",
                      "city": "SAN BARTOLOME DE TIRAJANA ",
                      "state": "PALMAS (LAS)"
                    }
                  ],
                  "email": "jdoe@ketchup.com",
                  "auditTrail": {
                    "creation": {
                      "user_id": "1",
                      "creationDate": "1559213796974"
                    },
                    "modification": [
                      {
                        "user_id": "1",
                        "modifDate": "1559213833358"
                      }
                    ]
                  }
                }
              ],
              "_id": "5cf629538c2d290f39a9b18b",
              "type": "customer",
              "name": "ginegorama",
              "vat": "B95551776",
              "activityNumber": "8690"
            }
          ],
          "salesRep": [
            {
              "user_id": "1",
              "dateBegin": "1559212324146",
              "active": true
            },
            {
              "user_id": "2",
              "dateBegin": "1559212324146",
              "active": false
            }
          ],
          "commentsArr": [
            {
              "user_id": "USER_ID to be changed to name",
              "comment": "this is a great customer!"
            }
          ],
          "_id": "5cf6296a8c2d290f39a9b18c",
          "auditTrail": {
            "modifications": [
              {
                "modificationDate": "1559211664284",
                "user_id": "1"
              }
            ],
            "creation": {
              "creationDate": "1559211664284",
              "user_id": "1"
            }
          },
          "docRefs": {
            "fs": [
              {
                "name": "mod 200 2018",
                "comment": "should be approved",
                "url": "/somewhere",
                "uploadDate": "1559212324146",
                "originalName": "mod200-2018.pdf",
                "mime": "pdf",
                "type": "fs",
                "typeName": "Financial Statements"
              }
            ],
            "id": [
    
            ],
            "ad": [
    
            ],
            "cd": [
    
            ],
            "pd": [
    
            ],
            "od": [
    
            ]
          },
          "active": false
        }
      ]
    }
    

    【讨论】:

      猜你喜欢
      • 2015-03-26
      • 2020-06-07
      • 2018-06-07
      • 2019-09-23
      • 2016-10-12
      • 1970-01-01
      • 2016-03-01
      • 2017-03-01
      相关资源
      最近更新 更多