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

Sử dụng toán tử $ slice để lấy phần tử cuối cùng của mảng

Như bạn đã biết bây giờ, $ slice chỉ được sử dụng trong phép chiếu để giới hạn các phần tử mảng được trả về trong kết quả. Vì vậy, bạn sẽ gặp khó khăn với việc xử lý danh sách theo chương trình với kết quả từ find ().

Một cách tiếp cận tốt hơn là sử dụng tổng hợp. Nhưng trước tiên, hãy xem xét cách $ lát được sử dụng:

> db.collection.find({},{ relevancy: {$slice: -1} })
{ "_id" : ObjectId("530824b95f44eac1068b45c0"), "relevancy" : [  "Y" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c2"), "relevancy" : [  "Y" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c3"), "relevancy" : [  "N" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c4"), "relevancy" : [  "Y" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c6"), "relevancy" : [  "N" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c7"), "relevancy" : [  "N" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c8"), "relevancy" : [  "N" ] }

Vì vậy, bạn nhận được phần tử mảng cuối cùng, nhưng bạn gặp khó khăn với việc lặp lại các kết quả vì bạn không thể khớp giá trị phần tử cuối cùng. Bạn cũng có thể vừa thực hiện điều này trong mã.

Bây giờ chúng ta hãy xem xét tổng hợp :

db.collection.aggregate([
    // Match things so we get rid of the documents that will never match, but it will
    // still keep some of course since they are arrays, that *may* contain "N"
    { "$match": { "relevancy": "Y" } },

    // De-normalizes the array
    { "$unwind": "$relevancy" },

    // The order of the array is retained, so just look for the $last by _id
    { "$group": { "_id": "$_id", "relevancy": { "$last": "$relevancy" } }},

    // Match only the records with the results you want
    { "$match": { "relevancy": "Y" }},

    // Oh, and maintain the original _id order [ funny thing about $last ]
    { "$sort": { "_id": 1 } }
])

Ngay cả khi đây là lần đầu tiên bạn sử dụng tổng hợp (), tôi khuyến khích bạn tìm hiểu nó . Nó có lẽ là công cụ giải quyết vấn đề hữu ích nhất của bạn. Chắc chắn đã được cho tôi. Thực hiện từng bước trong một lần tại một thời điểm nếu bạn đang học.

Cũng không chắc chắn trên biểu mẫu tài liệu của bạn, tất cả 1: { ... } ký hiệu tài liệu phụ dường như bị nhầm lẫn nhưng bạn nên xóa hoặc điều chỉnh mã ở trên để tham chiếu "1.relevancy" thay thế. Tôi hy vọng tài liệu của bạn thực sự trông giống như thế này:

{ "relevancy" : [  "Y" ] , "_id" : ObjectId("530824b95f44eac1068b45c0") }
{ "relevancy" : [  "Y",  "Y" ] , "_id" : ObjectId("530824b95f44eac1068b45c2") }
{ "relevancy" : [  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c3") }
{ "relevancy" : [  "Y",  "Y" ], "_id" : ObjectId("530824b95f44eac1068b45c4") }
{ "relevancy" : [  "Y",  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c6") }
{ "relevancy" : [  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c7") }
{ "relevancy" : [  "Y",  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c8") }

MongoDB 3.2.x trở lên

Tất nhiên MongoDB 3.2 giới thiệu toán tử "tổng hợp" cho $slice$arrayElemAt tốt hơn nữa toán tử loại bỏ sự cần thiết đối với bất kỳ $unwind nào và $group Chế biến. Sau $match ban đầu truy vấn bạn chỉ cần tạo một "đối sánh logic" với $redact :

db.collection.aggregate([
    { "$match": { "relevancy": "Y" } },
    { "$redact": {
        "$cond": {
            "if": { "$eq": [{ "$arrayElemAt": [ "$relevancy", -1 ], "Y" ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }
    }}   
])

Điều đó sẽ thực hiện kiểm tra phần tử cuối cùng của mảng khi quyết định có nên $$KEEP hay không hoặc $$PRUNE các tài liệu từ kết quả trả về.

Nếu bạn vẫn muốn "phép chiếu" thì bạn thực sự có thể thêm $slice :

db.collection.aggregate([
    { "$match": { "relevancy": "Y" } },
    { "$redact": {
        "$cond": {
            "if": { "$eq": [{ "$arrayElemAt": [ "$relevancy", -1 ], "Y" ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }
    }},
    { "$project": { "relevancy": { "$slice": [ "$relevancy", -1 ] } } }
])

Hoặc cách tiếp cận thay thế của:

db.collection.aggregate([
    { "$match": { "relevancy": "Y" } },
    { "$project": { "relevancy": { "$slice": [ "$relevancy", -1 ] } } },
    { "$match": { "relevancy": "Y" } }
])

Nhưng có lẽ ít tốn kém hơn khi thực hiện $redact đầu tiên và "sau đó" thực hiện bất kỳ sự định hình lại nào trong `$ project.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Lưu trữ các mối quan hệ bạn bè trong MongoDB?

  2. Mongo phân loại phức tạp?

  3. Có cách nào để ngăn MongoDB thêm dạng số nhiều vào tên bộ sưu tập không?

  4. Cách quản lý cơ sở dữ liệu lớn một cách hiệu quả

  5. Chèn và ngày truy vấn với MongoDB và Nodejs