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

Làm thế nào để tìm vào mongodb đến mục cuối cùng của một mảng?

Tôi biết câu hỏi này đã cũ nhưng tôi đã tìm thấy câu hỏi này trên google sau khi trả lời một câu hỏi mới tương tự . Vì vậy, tôi nghĩ điều này xứng đáng được đối xử tương tự.

Bạn có thể tránh ảnh hưởng hiệu suất của $ where bằng cách sử dụng tổng hợp thay vào đó:

db.example.aggregate([

    // Use an index, which $where cannot to narrow down
    {$match: { "comments.by": "Abe" }},

    // De-normalize the Array
    {$unwind: "$comments"},

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

    // Match only where that $last comment by `by.Abe`
    {$match: { "comments.by": "Abe" }},

    // Retain the original _id order
    {$sort: { _id: 1 }}

])

Và điều đó sẽ chạy vòng quanh $ where vì chúng tôi có thể thu hẹp các tài liệu một bình luận của "Abe" ở vị trí đầu tiên. Như đã cảnh báo, $ where sẽ kiểm tra mọi tài liệu trong bộ sưu tập và không bao giờ sử dụng chỉ mục ngay cả khi tài liệu đó được sử dụng.

Tất nhiên, bạn cũng có thể duy trì tài liệu gốc bằng cách sử dụng kỹ thuật được mô tả tại đây cũng vậy, vì vậy mọi thứ sẽ hoạt động giống như find() .

Chỉ là thức ăn để suy nghĩ cho bất kỳ ai tìm thấy thứ này.

Cập nhật cho các bản phát hành MongoDB hiện đại

Các bản phát hành hiện đại đã thêm $redact biểu thức đường ống cũng như $arrayElemAt (cái sau kể từ 3.2, vì vậy đó sẽ là phiên bản tối thiểu ở đây) khi kết hợp sẽ cho phép biểu thức logic kiểm tra phần tử cuối cùng của mảng mà không cần xử lý $unwind giai đoạn:

db.example.aggregate([
  { "$match": { "comments.by": "Abe" }},
  { "$redact": {
    "$cond": {
      "if": {
        "$eq": [
          { "$arrayElemAt": [ "$comments.by", -1 ] },
          "Abe"
        ]
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

Logic ở đây được thực hiện so với $arrayElemAt đang nhận chỉ mục cuối cùng của mảng -1 , được chuyển đổi chỉ thành một mảng các giá trị trong "by" thuộc tính qua $map . Điều này cho phép so sánh giá trị đơn lẻ với tham số bắt buộc, "Abe" .

Hoặc thậm chí hiện đại hơn một chút bằng cách sử dụng $expr cho MongoDB 3.6 trở lên:

db.example.find({
  "comments.by": "Abe",
  "$expr": {
    "$eq": [
      { "$arrayElemAt": [ "$comments.by", -1 ] },
      "Abe"
    ]
  }
})

Đây sẽ là giải pháp hiệu quả nhất để so khớp phần tử cuối cùng trong một mảng và thực sự được mong đợi sẽ thay thế việc sử dụng $where trong hầu hết các trường hợp và đặc biệt là ở đây.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Giá trị chuỗi rỗng MongoDB so với giá trị rỗng

  2. Cơ sở dữ liệu danh sách MongoDB với tiền tố đã cho trong Go

  3. Làm cách nào tôi có thể thêm trước một chuỗi vào mọi giá trị trong một mảng trong Mongoose?

  4. $ near yêu cầu điểm geojson, điểm geojson đã cho

  5. Cập nhật tài liệu nhúng trong MongoDB với trình điều khiển C # chính thức