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

Tìm hai phần tử trong một mảng tài liệu xuất hiện theo một thứ tự nhất định

Nếu bạn muốn loại ràng buộc đó trong truy vấn, thì về cơ bản bạn có hai tùy chọn tùy thuộc vào những gì phiên bản MongoDB của bạn hỗ trợ:

MongoDB 3.6

Bạn nên sử dụng $ expr "thêm vào" với bất kỳ điều kiện truy vấn thông thường nào để thực sự chọn tài liệu hợp lệ:

var A = 10, B = 40;

Model.find({
  "subDocs.value": { "$all": [A, B] },
  "$expr": {
    "$lt": [
      { "$arrayElemAt": [
        "$subDocs.index",
        { "$indexOfArray": [ "$subDocs.value", A ]}
      ]},
      { "$arrayElemAt": [
        "$subDocs.index",
        { "$indexOfArray": [ "$subDocs.value", B ]}  
      ]}
    ]
  }
})

Hoặc khớp với "cuối cùng" sự xuất hiện:

Model.find({
  "subDocs.value": { "$all": [A, B] },
  "$expr": {
    "$lt": [
      { "$arrayElemAt": [
        "$subDocs.index",
        { "$subtract": [
          { "$subtract": [{ "$size": "$subDocs.value" }, 1 ] },
          { "$indexOfArray": [ { "$reverseArray": "$subDocs.value" }, A ] }
        ]}
      ]},
      { "$arrayElemAt": [
        "$subDocs.index",
        { "$subtract": [
          { "$subtract": [{ "$size": "$subDocs.value" }, 1 ] },
          { "$indexOfArray": [ { "$reverseArray": "$subDocs.value" }, B ] }
        ]}
      ]}
    ]
  }
})

Các phiên bản trước đó

Tương tự, nhưng không có toán tử gốc, bạn cần sử dụng đánh giá JavaScript của $ ở đâu :

var A = 10, B = 40;

Model.find({
  "subDocs.value": { "$all": [A, B] },
  "$where": `this.subDocs.find( e => e.value === ${A}).index
      < this.subDocs.find( e => e.value === ${B}).index`
})

Hoặc khớp với "cuối cùng" sự xuất hiện:

Model.find({
  "subDocs.value": { "$all": [10,40] },
  "$where": `let arr = this.subDocs.reverse();
      return arr.find( e => e.value === ${A}).index
        > arr.find( e => e.value === ${B}).index`
})

Nếu bạn cần điều đó trong quy trình tổng hợp, thì bạn sẽ sử dụng $ redact và logic tương tự như ví dụ đầu tiên để thay thế:

var A = 10, B = 40;

Model.aggregate([
  { "$match": { "subDocs.value": { "$all": [A, B] } } },
  { "$redact": {
    "$cond": {
      "if": {
        "$lt": [
          { "$arrayElemAt": [
            "$subDocs.index",
            { "$indexOfArray": [ "$subDocs.value", A ]}
          ]},
          { "$arrayElemAt": [
            "$subDocs.index",
            { "$indexOfArray": [ "$subDocs.value", B ]}  
          ]}
        ]
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

Chỉ cần nói rằng "logic so sánh" không thực sự có nguồn gốc từ chính "các biểu thức toán tử truy vấn", vì vậy, phần duy nhất mà "tối ưu" có thể được áp dụng cho một chỉ mục đang sử dụng $ all toán tử truy vấn trong mọi trường hợp. Logic cơ bản còn lại thực sự áp dụng "sau khi" biểu thức chính được đánh giá và "bổ sung" để không có kết quả nào được trả về khác với những kết quả đáp ứng biểu thức với $expr hoặc $ where .

Logic cơ bản của mỗi loại về cơ bản là trích xuất giá trị của "index" thuộc tính từ thành viên mảng "đầu tiên" thực sự khớp với giá trị tương ứng trong "value" tài sản. Trường hợp giá trị này là "nhỏ hơn", thì điều kiện là true và điều này thỏa mãn tài liệu đang được trả lại.

Vì vậy, lưu ý rằng "đánh giá được tính toán" phù hợp với hiệu quả của toán tử truy vấn và không được sử dụng "kết hợp" với các điều kiện toán tử truy vấn khác có thể truy cập "chỉ mục", thì "quét toàn bộ bộ sưu tập" sẽ được bắt đầu.

Nhưng kết quả tổng thể chắc chắn hiệu quả hơn việc trả lại tất cả các mục phù hợp với điều kiện truy vấn đầu tiên và sau đó từ chối chúng trên con trỏ "sau khi" quay trở lại từ cơ sở dữ liệu.

Xem thêm tài liệu về $ arrayElemAt , $ indexOfArray , $ lt Array.find () cho JavaScript




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Chỉ mục văn bản MongoDB trên tất cả các trường sử dụng Java

  2. Đồ thị DBs so với DB tài liệu so với Triplestores

  3. Mongoose chỉ mục duy nhất trên subocument

  4. Xác thực MongoDB 3.2 không thành công

  5. Tra cứu tổng hợp Mongo 3.6 với nhiều điều kiện