2013-04-10 30 views
7

xem xét sau đây là tài liệu của tôi được lưu trữ trong bộ sưu tập UsersMongoDB khuôn khổ hợp - Fetch trường đầu tiên tài liệu của mảng lồng nhau

{ 
    _id : "User1", 
    joined : ISODate("2011-03-02"), 
    likes : { 
      sublikes: [ 
         {WebsiteID:'001': WebsiteName: 'ABCD'}, 
         {WebsiteID:'002': WebsiteName: '2BC2'}, 
         {WebsiteID:'003': WebsiteName: '3BC3'}, 
         //........... 
         //........... 
         {WebsiteID:'999999': WebsiteName: 'SOME_NAME'} 
        ] 
      } 
} 

Bây giờ sử dụng khuôn khổ MongoDB tập hợp tôi cần phải lấy đó

collection.aggregate([ 
         { $project: { 
          _id: 1, 
          "UserID": "$_id", 
          "WebsiteName": "$likes.sublikes[0]['WebsiteName']" 
         } 
         }, 
         { $match: { _id: 'User1'} } 
         ], function (err, doc) { 
///Not able to get the WebsiteName: 'ABCD' 
}); 

Nếu Tôi sử dụng $unwind tài liệu trở thành số lượng lớn (cụ thể trong trường hợp trên), Vì vậy, tôi không muốn để thư giãn nó chỉ nhận được mục đầu tiên trong một mảng (không phân biệt người khác)

Có ai cho tôi gợi ý về cách truy cập và đổi tên trường đó không?


Cập nhật 1: Ngay cả khi tôi đã cố gắng chiếu với "WebsiteName": "$likes.sublikes.0.WebsiteName". Không làm việc :-(

Cập nhật 2:. Mở vấn đề - https://jira.mongodb.org/browse/SERVER-4589

Tính đến nay $at không hoạt động Ném một lỗi:

{ [MongoError: exception: invalid operator '$at'] 
    name: 'MongoError', 
    errmsg: 'exception: invalid operator \'$at\'', 
    code: 15999, 
    ok: 0 } 

Till sau đó sử dụng $unwind

// Array Remove - By John Resig (MIT Licensed) 
Array.prototype.remove = function(from, to) { 
    var rest = this.slice((to || from) + 1 || this.length); 
    this.length = from < 0 ? this.length + from : from; 
    return this.push.apply(this, rest); 
}; 
+0

Thay vào đó, bạn sẽ không sử dụng truy vấn thông thường với toán tử $ slice (http://docs.mongodb.org/manual/reference/projection/slice/) như sau: 'db.col.find ({_ id: ' User1 '}, {' likes.sublikes ': {$ slice: 1}}) '? – Sammaye

+1

Sự cố mở trong Jira mà bạn đã tham chiếu (SERVER-4589) là yêu cầu tính năng để toán tử '$ at' chưa tồn tại. Bạn có thể bỏ phiếu/xem tính năng trong Jira để theo dõi tiến độ. – Stennie

+1

FYI, bạn cũng nên có '$ match' của bạn ở đầu đường ống tổng hợp nếu bạn muốn nó tận dụng lợi thế của chỉ mục. Xem chi tiết [Tối ưu hóa hiệu suất] (http://docs.mongodb.org/manual/core/aggregation/#optimizing-performance) trong tài liệu MongoDB. – Stennie

Trả lời

10

Cách dễ nhất để đạt được kết quả của bạn đang sử dụng một truy vấn tìm bình thường và $slice điều hành:

db.collection.find({_id: "User1"}, {"likes.sublikes": {$slice: 1}}) 

Khung tập hợp (như ở MongoDB 2.4.1) không hỗ trợ $slice hoặc mảng chỉ số (yêu cầu tính năng bỏ phiếu/xem: SERVER-6074SERVER-4589).

Bạn có thể làm điều này trong khuôn khổ hợp sử dụng $unwind, $group$first điều hành, ví dụ:

db.collection.aggregate([ 
    { $match: { 
     _id : "User1" 
    }}, 
    { $unwind: "$likes.sublikes" }, 
    { $group: { 
     _id: "$_id", 
     like: { $first: "$likes.sublikes" } 
    }}, 
    { $project: { 
     _id: 0, 
     "UserID": "$_id", 
     "WebsiteName": "$like.WebsiteName" 
    }} 
]) 

Các bình thường $slice nên là lựa chọn performant nhất.

+1

rất đẹp .. nó hoạt động ... –

Các vấn đề liên quan