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

Điều kiện phù hợp của các thành viên trong mảng tổng hợp

Lỗi là do nó không còn là một mảng sau khi bạn $ unwind và do đó không còn là đối số hợp lệ cho $ size .

Có vẻ như bạn đang cố gắng "hợp nhất" một vài câu trả lời hiện có mà không hiểu chúng đang làm gì. Điều bạn thực sự muốn ở đây là $ filter $ size

db.collection.aggregate([
  { "$project": {
    "total": {
      "$size": {
        "$filter": {
          "input": "$Array",
          "cond": { "$eq": [ "$$this.field1", "a" ] }
        }
      }
    }
  }}
])

Hoặc "phát minh lại bánh xe" bằng cách sử dụng $ Reduce :

db.collection.aggregate([
  { "$project": {
    "total": {
      "$reduce": {
        "input": "$Array",
        "initialValue": 0,
        "in": {
          "$sum": [
            "$$value", 
            { "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
        }
      }
    }
  }}
])

Hoặc cho những gì bạn đang cố gắng thực hiện với $ unwind , bạn thực sự $ group một lần nữa để "đếm" có bao nhiêu trận đấu:

db.collection.aggregate([
  { "$unwind": "$Array" },
  { "$match": { "Array.field1": "a" } },
  { "$group": {
    "_id": "$_id",
    "total": { "$sum": 1 }
  }}
])

Hai hình thức đầu tiên là "tối ưu" cho môi trường MongoDB hiện đại. Biểu mẫu cuối cùng với $ unwind $ group là một cấu trúc "kế thừa" thực sự không cần thiết cho loại hoạt động này kể từ MongoDB 2.6, mặc dù với một số toán tử hơi khác.

Trong hai đầu tiên đó, về cơ bản, chúng ta đang so sánh field1 giá trị của mỗi phần tử mảng trong khi nó vẫn là một mảng. Cả $ filter $ giảm là các toán tử hiện đại được thiết kế để làm việc với một mảng hiện có tại chỗ. Việc so sánh tương tự được thực hiện trên từng cái bằng cách sử dụng tổng hợp $ eq toán tử trả về giá trị boolean dựa trên việc các đối số được đưa ra có "bằng" hay không. Trong trường hợp này, trên mỗi thành viên mảng giá trị mong đợi là "a" .

Trong trường hợp của $ filter , mảng thực sự vẫn nguyên vẹn ngoại trừ bất kỳ phần tử nào không đáp ứng điều kiện được cung cấp trong "cond" bị xóa khỏi mảng. Vì chúng ta vẫn có "mảng" làm đầu ra, nên sau đó, chúng ta có thể sử dụng $ size toán tử để đo số phần tử mảng còn lại sau khi điều kiện lọc đó được xử lý.

$ giảm mặt khác, hoạt động thông qua các phần tử của mảng và cung cấp một biểu thức cho mỗi phần tử và một giá trị "bộ tích lũy" được lưu trữ, mà chúng tôi đã khởi tạo bằng "initialValue" . Trong trường hợp này, cùng một $ eq kiểm tra được áp dụng trong $ cond nhà điều hành. Đây là "bậc ba" hoặc if / then / else toán tử điều kiện cho phép một biểu thức được kiểm tra trả về giá trị boolean để trả về then giá trị khi true hoặc else giá trị khi false .

Trong biểu thức đó, chúng ta trả về 1 hoặc 0 tương ứng và cung cấp kết quả tổng thể của việc thêm giá trị trả về đó và "bộ tích lũy" "$$ value" hiện tại với $ sum toán tử để thêm chúng lại với nhau.

Biểu mẫu cuối cùng được sử dụng $ unwind trên mảng. Điều này thực sự làm là giải cấu trúc các thành viên mảng để tạo một "tài liệu mới" cho mọi thành viên mảng và các trường cha liên quan của nó trong tài liệu gốc. Điều này "sao chép" tài liệu chính một cách hiệu quả cho mọi thành viên mảng.

Sau khi bạn $ unwind cấu trúc của các tài liệu được thay đổi sang dạng "phẳng hơn". Đây là lý do tại sao bạn có thể thực hiện $ so khớp tiếp theo giai đoạn đường ống để loại bỏ các tài liệu không khớp.

Điều này đưa chúng tôi đến $ group được áp dụng để "tập hợp lại" tất cả thông tin liên quan đến một khóa chung. Trong trường hợp này, đó là _id trường của tài liệu gốc, tất nhiên đã được sao chép vào mọi tài liệu được tạo bởi $ unwind . Khi quay lại "khóa chung" này dưới dạng một tài liệu, chúng tôi có thể "đếm" các "tài liệu" còn lại được trích xuất từ ​​mảng bằng cách sử dụng $ sum bộ tích lũy.

Nếu chúng tôi muốn lấy lại "mảng" còn lại, thì bạn có thể $ push và xây dựng lại mảng chỉ với các thành viên còn lại:

  { "$group": {
    "_id": "$_id",
    "Array": { "$push": "$Array" },
    "total": { "$sum": 1 }
  }}

Nhưng tất nhiên thay vì sử dụng $ size trong một giai đoạn quy trình khác, chúng ta vẫn có thể "đếm" đơn giản như chúng ta đã làm với $ sum




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Làm cách nào để nhận đầu ra và trình bao truy vấn được tô màu trong MongoDB?

  2. phần mongodb của objectid có nhiều khả năng là duy nhất

  3. Nhóm có điều kiện với $ tồn tại bên trong $ cond

  4. MongoParseError:Chuỗi kết nối không hợp lệ

  5. Lấy tổ tiên trong MongoDb bằng cách sử dụng cấu trúc cây