猫鼬:填充ID的嵌套数组

时间:2019-07-29 14:45:52

标签: mongoose mongoose-schema mongoose-populate

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

客户架构:

ID

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

第三方:

# rides_df and station_df are slightly modified to make sure that the code works as intended
rides_df = pd.DataFrame([[1912818,'Round Trip',3014,34.0566101,-118.23721,3014,34.0566101,-118.23721],
                 [1933383,'Round Trip',3016,34.0528984,-118.24156,3016,34.0528984,-118.24156],
                  [1944197,'Round Trip',3016,34.0528984,-118.24156,3016,34.0528984,-118.24156],
                  [1940317,'Round Trip','NaN' ,34.03352,-118.24184,3018,34.03352,-118.24184],
                  [1944075,'One Way',3021,34.0456085,-118.23703,3016,34.0566101,-118.23721]]
                 , columns = ['trip_id','trip_route_category','start_station_id','start_lat',
                              'start_lon','end_station_id','end_lat','end_lon'])                          

stations_df = pd.DataFrame([['Union Station West Portal',34.05661,-118.23721,'NaN'],
                            ['Los Angeles & Temple',34.0529,-118.24156,3016],
                            ['Grand & Olympic',34.04373,-118.26014,3018],
                            ['12th & Hill',34.03861,-118.26086,3019],
                            ['Hill & Washington',34.03105,-118.26709,3020],
                            ['Row DTLA',34.03352,-118.24184,'NaN']], 
                           columns = ['station_name', 'lat', 'lon','station_id'])


# Convert to floats to match NaNs
rides_df[["start_station_id", "end_station_id"]] = rides_df[["start_station_id", "end_station_id"]].astype(float)
stations_df["station_id"] = stations_df["station_id"].astype(float)
# Convert the NaNs to another invalid id so they stop matching on merge
stations_df.loc[stations_df["station_id"].isnull(), "station_id"] = -1
# Round so numbers are an exact match
rides_df = rides_df.round(5)

# Merge beginning station name
rides_df = rides_df.rename(columns = {'start_station_id': 'station_id', 
                                      'start_lat': 'lat', 'start_lon': 'lon'})
rides_df = rides_df.merge(stations_df[['station_id','station_name']],
                         on = 'station_id', how = 'left')
# Merge again by looking at lat/lon values
rides_df = rides_df.merge(stations_df[['lat', 'lon','station_name']],
                         on = ['lat', 'lon'], how = 'left')
# Merge the two merge results
rides_df.loc[:, "station_name"] = rides_df["station_name_x"].combine(rides_df["station_name_y"], lambda x,y: x if not x!=x else y)
rides_df.drop(["station_name_x", "station_name_y"], axis=1, inplace=True)
rides_df = rides_df.rename(columns = {'station_id':'start_station_id',
                                     'station_name':'start_station_name', 
                                     'lat':'start_lat', 'lon':'start_lon'})

# Merge ending station name
rides_df = rides_df.rename(columns = {'end_station_id': 'station_id',
                                      'start_lat': 'lat', 'start_lon': 'lon'})
rides_df = rides_df.merge(stations_df[['station_id', 'station_name']],
                         on = 'station_id', how = 'left')
rides_df = rides_df.merge(stations_df[['lat', 'lon','station_name']],
                         on = ['lat', 'lon'], how = 'left')
rides_df.loc[:, "station_name"] = rides_df["station_name_x"].combine(rides_df["station_name_y"], lambda x,y: x if not x!=x else y)
rides_df.drop(["station_name_x", "station_name_y"], axis=1, inplace=True)
rides_df = rides_df.rename(columns = {'station_id':'end_station_id',
                                     'station_name': 'end_station_name',
                                     'lat':'start_lat', 'lon':'start_lon'})

print(rides_df)

和联系人:

   trip_id trip_route_category  start_station_id  start_lat  start_lon  end_station_id   end_lat    end_lon         start_station_name           end_station_name
0  1912818          Round Trip            3014.0   34.05661 -118.23721          3014.0  34.05661 -118.23721  Union Station West Portal  Union Station West Portal
1  1933383          Round Trip            3016.0   34.05290 -118.24156          3016.0  34.05290 -118.24156       Los Angeles & Temple       Los Angeles & Temple
2  1944197          Round Trip            3016.0   34.05290 -118.24156          3016.0  34.05290 -118.24156       Los Angeles & Temple       Los Angeles & Temple
3  1940317          Round Trip               NaN   34.03352 -118.24184          3018.0  34.03352 -118.24184                   Row DTLA            Grand & Olympic
4  1944075             One Way            3021.0   34.04561 -118.23703          3016.0  34.05661 -118.23721                        NaN       Los Angeles & Temple

这是我的电话:

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}
});

如果在客户内部完全填充了ThirdParty,则联系人绝对不会... 这是“响应”的日志: Log of the call

我在做什么错?

谢谢!

2 个答案:

答案 0 :(得分: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"
    }]
  }]
}

答案 1 :(得分:0)

知道了!我在模型中缺少导入语句:

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
    }
  ]
}