2017-01-25 53 views
2

我是相当新的猫鼬,我想写一个查询,只是返回我的主文档中的一个子文档。查询显示子文档不工作

我的文档结构是这样的:

PROFILE 
    - CONTACTS [ARRAY] 

我已经写了下面的终点返回一个触点,在那里我通过配置文件ID和子文档的ID:

“/: owerId/getcontact /:使用ContactID”

我的快递功能的代码如下所示:

router.route('/:ownerId/getcontact/:contactId') 

    .get(function(req, res){ 
     Profile.findOne({'owner_id':req.params.ownerId}).then(function(err, profile){ 
     if(err) 
      res.send(err); 

     profile.findOne({'_id':req.params.contactId}).then(function(err, contact){ 
      if(err) 
      res.send(err); 
      res.json(contact); 
     }) 

     }) 
    }) 

但是这个代码返回整个配置文件。

当我尝试通过ID获取它做同样的事情。这里是我的代码,只是下面是返回的整个轮廓:

router.route('/:ownerId/getcontact/:contactId') 

.get(function(req, res){ 
    Profile.findById(req.params.ownerId).then(function(err, profile){ 
    if(err) 
     res.send(err); 

     var data = profile.contacts.id(req.params.contactId); 

    res.json(data); 

    }) 
}) 





{ 
    "_id": "5886e3692ca4542c453431ee", 
    "initial": "u", 
    "last_name": "randal", 
    "first_name": "chris", 
    "owner_id": "5886e32c2ca4542c453431ed", 
    "__v": 1, 
    "contacts": [ 
    { 
     "last_name": "Eltoro", 
     "first_name": "Peter", 
     "_id": "5886e3f5a219472cac886a9f", 
     "businesses": [], 
     "addresses": [], 
     "phones": [ 
     { 
      "phone_type": "mobile", 
      "phone_number": "555-555-999", 
      "_id": "5886e3f5a219472cac886aa2" 
     }, 
     { 
      "phone_type": "home", 
      "phone_number": "999-876-000", 
      "_id": "5886e3f5a219472cac886aa1" 
     } 
     ], 
     "emails": [ 
     { 
      "email_address": "[email protected]", 
      "_id": "5886e3f5a219472cac886aa0" 
     } 
     ] 
    }, 
    { 
     "college": "University of WA", 
     "highschool": "Kalaheo", 
     "birthday": "1990-12-22T08:00:00.000Z", 
     "last_name": "Smith", 
     "first_name": "Suzanne", 
     "_id": "5886fb7fac288c2e31eabe0a", 
     "businesses": [], 
     "addresses": [ 
     { 
      "zip": "98777", 
      "state": "WA", 
      "city": "Seattle", 
      "address_2": "Apt 234", 
      "address": "124 194th St. SW", 
      "_id": "5886fb7fac288c2e31eabe0e" 
     } 
     ], 
     "phones": [ 
     { 
      "phone_type": "mobile", 
      "phone_number": "206-899-9898", 
      "_id": "5886fb7fac288c2e31eabe0d" 
     }, 
     { 
      "phone_type": "home", 
      "phone_number": "206-789-0987", 
      "_id": "5886fb7fac288c2e31eabe0c" 
     } 
     ], 
     "emails": [ 
     { 
      "email_type": "personal", 
      "email_address": "[email protected]", 
      "_id": "5886fb7fac288c2e31eabe0b" 
     } 
     ] 
    }, 
    { 
     "last_name": "Alabaster", 
     "first_name": "Cindy", 
     "_id": "5888b0bd3c025e54476828d9", 
     "businesses": [], 
     "addresses": [], 
     "phones": [ 
     { 
      "phone_type": "home", 
      "phone_number": "999-999-0909", 
      "_id": "5888b0bd3c025e54476828dc" 
     }, 
     { 
      "phone_type": "home", 
      "phone_number": "000-000-0000", 
      "_id": "5888b0bd3c025e54476828db" 
     } 
     ], 
     "emails": [ 
     { 
      "email_address": "[email protected]", 
      "_id": "5888b0bd3c025e54476828da" 
     } 
     ] 
    } 
    ], 
    "businesses": [], 
    "addresses": [], 
    "phones": [ 
    { 
     "phone_number": "999-999-9999", 
     "phone_type": "mobile", 
     "_id": "5886e37f2ca4542c453431ef" 
    } 
    ], 
    "emails": [] 
} 

回答

0

猫鼬子文档具有特殊的方法来检索他们:

router 
    .route('/:ownerId/getcontact/:contactId') 
    .get(function(req, res) { 
     Profile.findOne({ owner_id: req.params.ownerId }, function(err, profile) { 
     if (err) { 
      res.send(err); 
     } 
     var contact = profile.contacts.id(req.params.contactId); 
     res.json(contact); 
     }); 
    }); 

Mongoose Sub Documents

+0

谢谢,dNitro,但我得到了相同的结果。看到我的更新... – cnak2

+0

这是因为你的个人资料'_id'与'owner_id'不同,所以你不应该使用'findById'你应该使用'findOne'。答案已更新。 – dNitro

+0

我更改了ownerId参数以包含_id。我只是没有改变param的名字。所以它实际上是通过_id查找配置文件。我试过findOne和findById,出于某种原因,我仍然把整个记录取回来,而不仅仅是子文档。奇怪。 – cnak2

0

另一种途径是通过聚合框架,您可以使用$match$arrayElemAt$filter运营商来返回你想要的数据。

考虑在运行下列聚合操作的API端点实现:

router.route('/:ownerId/getcontact/:contactId') 
    .get(function(req, res){ 
     var ownerId = mongoose.Schema.Types.ObjectId(req.params.ownerId), 
      contactId = mongoose.Schema.Types.ObjectId(req.params.contactId); 

     Profile.aggregate([ 
      { "$match": { "owner_id": ownerId } }, 
      { 
       "$project": { 
        "contact": { 
         "$arrayElemAt": [ 
          { 
           "$filter": { 
            "input": "$contacts", 
            "as": "contact", 
            "cond": { "$eq": ["$$contact._id", contactId] } 
           } 
          }, 
          0 
         ] 
        } 
       } 
      } 
     ]).exec(function(err, profile){ 
      if(err) res.send(err);   
      res.json(profile[0].contact); 
     }) 
    })