2017-01-25 105 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); 
     }) 
    })