MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Tôi có thể sử dụng điền trước khi tổng hợp trong mongoose không?

Không, bạn không thể gọi .populate() trước .aggregate() , và có một lý do chính đáng khiến bạn không thể. Nhưng có những cách tiếp cận khác nhau mà bạn có thể thực hiện.

.populate() phương thức hoạt động ở "phía máy khách" nơi mã cơ bản thực sự thực hiện các truy vấn bổ sung (hoặc chính xác hơn là $in truy vấn) để "tra cứu" (các) phần tử được chỉ định từ tập hợp được tham chiếu.

Ngược lại .aggregate() là hoạt động "phía máy chủ", vì vậy về cơ bản bạn không thể thao tác nội dung "phía máy khách", và sau đó có sẵn dữ liệu đó cho các giai đoạn đường ống tổng hợp sau này. Tất cả đều cần phải có trong bộ sưu tập mà bạn đang vận hành.

Ở đây có một cách tiếp cận tốt hơn với MongoDB 3.2 trở lên, thông qua $lookup vận hành đường ống tổng hợp. Cũng có lẽ tốt nhất nên xử lý từ User trong trường hợp này để thu hẹp lựa chọn:

User.aggregate(
    [
        // Filter first
        { "$match": {
            "age": { "$gt": 20 } 
        }},
        // Then join
        { "$lookup": {
            "from": "scores",
            "localField": "userID",
            "foriegnField": "userID",
            "as": "score"
        }},
        // More stages
    ],
    function(err,results) {

    }
)

Về cơ bản, điều này sẽ bao gồm một trường mới "điểm" trong User đối tượng dưới dạng "mảng" các mục phù hợp trên "tra cứu" với bộ sưu tập khác:

{
    "userID": "abc",
    "age": 21,
    "score": [{
        "userID": "abc",
        "score": 42,
        // other fields
    }]
}

Kết quả luôn là một mảng, vì cách sử dụng được mong đợi chung là "kết hợp bên trái" của một mối quan hệ có thể có "một đến nhiều". Nếu không có kết quả nào được so khớp thì nó chỉ là một mảng trống.

Để sử dụng nội dung, chỉ cần làm việc với một mảng theo bất kỳ cách nào. Ví dụ:bạn có thể sử dụng $arrayElemAt để chỉ lấy phần tử đầu tiên duy nhất của mảng trong bất kỳ hoạt động nào trong tương lai. Và sau đó, bạn chỉ có thể sử dụng nội dung như bất kỳ trường nhúng thông thường nào:

        { "$project": {
            "userID": 1,
            "age": 1,
            "score": { "$arrayElemAt": [ "$score", 0 ] }
        }}

Nếu bạn không có sẵn MongoDB 3.2, thì tùy chọn khác của bạn để xử lý một truy vấn bị giới hạn bởi các mối quan hệ của một tập hợp khác là trước tiên lấy kết quả từ tập hợp đó và sau đó sử dụng $in để lọc thứ hai:

// Match the user collection
User.find({ "age": { "$gt": 20 } },function(err,users) {

    // Get id list      
    userList = users.map(function(user) {
       return user.userID;
    });

    Score.aggregate(
        [ 
            // use the id list to select items
            { "$match": {
                "userId": { "$in": userList }
            }},
            // more stages
        ],
        function(err,results) {

        }
    );

});

Vì vậy, bằng cách nhận danh sách người dùng hợp lệ từ bộ sưu tập khác cho khách hàng và sau đó cung cấp danh sách đó cho bộ sưu tập khác trong một truy vấn là cách trực tiếp để điều này xảy ra trong các bản phát hành trước đó.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Truy vấn MongoDB với điều kiện 'hoặc'

  2. mongodb, pymongo, tổng hợp cho kết quả lạ (một cái gì đó về con trỏ)

  3. Hợp nhất hai trường mảng trong mongoDB

  4. Làm cách nào để sử dụng GraphQL với Mongoose và MongoDB mà không cần tạo mô hình Mongoose

  5. Mảng đối tượng trong lược đồ Mongoose