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

$ In khoản của MongoDB có đảm bảo thứ tự không

Như đã lưu ý, thứ tự của các đối số trong mảng của mệnh đề $ in không phản ánh thứ tự của cách tài liệu được truy xuất. Tất nhiên đó sẽ là thứ tự tự nhiên hoặc theo thứ tự chỉ mục đã chọn như được hiển thị.

Nếu bạn cần duy trì đơn đặt hàng này, thì về cơ bản bạn có hai lựa chọn.

Vì vậy, giả sử rằng bạn đang khớp trên các giá trị của _id trong tài liệu của bạn với một mảng sẽ được chuyển vào $in dưới dạng [ 4, 2, 8 ] .

Phương pháp tiếp cận sử dụng Tổng hợp

var list = [ 4, 2, 8 ];

db.collection.aggregate([

    // Match the selected documents by "_id"
    { "$match": {
        "_id": { "$in": [ 4, 2, 8 ] },
    },

    // Project a "weight" to each document
    { "$project": {
        "weight": { "$cond": [
            { "$eq": [ "$_id", 4  ] },
            1,
            { "$cond": [
                { "$eq": [ "$_id", 2 ] },
                2,
                3
            ]}
        ]}
    }},

    // Sort the results
    { "$sort": { "weight": 1 } }

])

Vì vậy, đó sẽ là dạng mở rộng. Điều cơ bản xảy ra ở đây là giống như mảng giá trị được chuyển tới $in bạn cũng tạo một $cond "lồng nhau" câu lệnh để kiểm tra các giá trị và ấn định trọng số thích hợp. Vì giá trị "trọng số" đó phản ánh thứ tự của các phần tử trong mảng, sau đó bạn có thể chuyển giá trị đó sang một giai đoạn sắp xếp để nhận được kết quả của bạn theo thứ tự bắt buộc.

Tất nhiên bạn thực sự "xây dựng" câu lệnh đường ống trong mã, giống như sau:

var list = [ 4, 2, 8 ];

var stack = [];

for (var i = list.length - 1; i > 0; i--) {

    var rec = {
        "$cond": [
            { "$eq": [ "$_id", list[i-1] ] },
            i
        ]
    };

    if ( stack.length == 0 ) {
        rec["$cond"].push( i+1 );
    } else {
        var lval = stack.pop();
        rec["$cond"].push( lval );
    }

    stack.push( rec );

}

var pipeline = [
    { "$match": { "_id": { "$in": list } }},
    { "$project": { "weight": stack[0] }},
    { "$sort": { "weight": 1 } }
];

db.collection.aggregate( pipeline );

Tiếp cận bằng mapReduce

Tất nhiên, nếu tất cả những điều đó dường như quá lớn đối với sự nhạy cảm của bạn thì bạn có thể làm điều tương tự bằng cách sử dụng mapReduce, trông đơn giản hơn nhưng có thể sẽ chạy chậm hơn một chút.

var list = [ 4, 2, 8 ];

db.collection.mapReduce(
    function () {
        var order = inputs.indexOf(this._id);
        emit( order, { doc: this } );
    },
    function() {},
    { 
        "out": { "inline": 1 },
        "query": { "_id": { "$in": list } },
        "scope": { "inputs": list } ,
        "finalize": function (key, value) {
            return value.doc;
        }
    }
)

Và điều đó về cơ bản dựa vào các giá trị "khóa" được phát ra nằm trong "thứ tự chỉ mục" về cách chúng xuất hiện trong mảng đầu vào.

Vì vậy, đó về cơ bản là những cách bạn duy trì thứ tự của danh sách đầu vào đến $in điều kiện là bạn đã có danh sách đó theo một thứ tự xác định.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Hình dung cấu trúc liên kết cụm của bạn trong ClusterControl

  2. 6 Công cụ hữu ích để theo dõi hiệu suất MongoDB

  3. Nhóm MongoDB theo mảng phần tử bên trong

  4. MongoDB $ atan2

  5. Sắp xếp với một chỉ mục hoạt động như thế nào trong MongoDB?