Bộ lọc mảng MongoDB

Hóa ra $project không hỗ trợ $elemMatch trong tổng hợp. Trong 3. 2, họ đã giới thiệu bộ lọc, v.v., điều này dường như không giải quyết được vấn đề của tôi.  

Hãy để tôi giải thích những gì tôi đang cố gắng thực hiện, giả sử tôi có các tài liệu sau trong cơ sở dữ liệu

    db.test.insert(
    {
      "ad_account_id": 150,
      "internal_id": 1,
      "daily": [{
        "timestamp": "2016-12-01",
        "impressions": 5
      }, {
        "timestamp": "2016-12-06",
        "impressions": 7
      }]
    })

    db.test.insert(
    {
      "ad_account_id": 150,
      "internal_id": 2,
      "daily": [{
        "timestamp": "2016-12-03",
        "impressions": 6
      }]
    })

    db.test.insert({
      "ad_account_id": 150,
      "internal_id": 3,
      "daily": []
    })

    db.test.insert({
      "ad_account_id": 16,
      "internal_id": 3,
      "daily": []
    })

Bây giờ, giả sử người dùng truy vấn ad_account_id. 150 và lọc theo phạm vi ngày bắt đầu và ngày kết thúc là "2016-12-01" đến "2016-12-02"

Truy vấn tổng hợp của tôi đọc như thế này (bỏ qua sắp xếp, giới hạn, v.v.)

    db.getCollection('test').aggregate({
            "$match" : {
              "ad_account_id" : 150,
              "daily" : {
                "$elemMatch" : {
                  "timestamp" : {
                    "$lte" : "2016-12-02",
                    "$gte" : "2016-12-01"
                  }
                }
              }
            }
          },
          {
            "$unwind" : "$daily"
          },
          {
            "$match" : {
              "daily.timestamp" : {
                "$lte" : "2016-12-02",
                "$gte" : "2016-12-01"
              }
            }
          },
          {
            "$group" : {
              "impressions" : {
                "$sum" : "$daily.impressions"
              },
              "ad_account_id" : {
                "$first" : "$ad_account_id"
              },
              "_id" : "$internal_id"
            }
          },
          {
            "$project" : {
              "impressions" : 1,
              "ga_transactions" : 1,
              "ad_account_id" : 1
            }
          }
    );

    { "_id" : 1, "impressions" : 5, "ad_account_id" : 150 }


Trong quá trình phát triển tại địa phương của chúng tôi, ban đầu có vẻ ổn. Truy vấn nhanh ngay cả với một triệu tài liệu và chúng tôi rất hài lòng.  

Nhưng chúng tôi đã sớm nhận ra trường hợp sử dụng của mình, nơi chúng tôi cần hiển thị các hàng ngay cả khi dữ liệu hàng ngày không nằm giữa ngày bắt đầu và ngày kết thúc. Số lần hiển thị, v.v. trong đó có thể được biểu thị bằng 0 nhưng chúng phải được hiển thị chắc chắn

Vì vậy, **kết quả mong muốn** mà chúng tôi muốn là thế này

     { "_id" : 1, "impressions" : 5, "ad_account_id" : 150 }
     { "_id" : 2, "impressions" : 0, "ad_account_id" : 150 }
     { "_id" : 3, "impressions" : 0, "ad_account_id" : 150 }

Và tôi đã vật lộn với điều này trong vài giờ qua vì dường như tôi không thể hiểu điều này trong một truy vấn mongo. Tôi nghĩ rằng tôi sẽ giới hạn đối sánh của mình chỉ với id tài khoản quảng cáo, sau đó thực hiện dự án $ và nếu không có dữ liệu nào giữa phạm vi dữ liệu đó, tôi sẽ chỉ thêm một mục nhập mẫu vào hàng ngày với dữ liệu bắt đầu dưới dạng dấu thời gian đại loại như thế này.  

    {
      "ad_account_id": 150,
      "internal_id": 3,
      "daily": [{timestamp: "2016-02-01"}]
    )

Nhưng thật không may, tôi không thể làm việc này, vì trong $project bạn không thể làm $elemMatch. Những thứ mới như $filter, v.v. dường như không giải quyết được vấn đề của tôi.  

Tôi cũng đã thử liên minh, và tôi nghĩ nó cũng gần như vậy

    db.getCollection('test').aggregate(
        {
            "$match" : {
              "ad_account_id" : 150,
              "daily" : {
                "$elemMatch" : {
                  "timestamp" : {
                    "$lte" : "2016-12-02",
                    "$gte" : "2016-12-01"
                  }
                }
              }
            }
          },
          { "$project": {
            "ad_account_id": 1,
            "daily": {
                "$setUnion": [
                    { "$map": {
                        "input": "$daily",
                        "as": "day",
                        "in": {
                            "$cond": [
                                { "$and": [
                                    { "$gte": [ "$day.timestamp", "2016-12-01" ] },
                                    { "$lte": [ "$day.timestamp", "2016-12-02" ] }
                                ]},
                                "$day",
                                false
                            ]
                        }
                    }},
                    [{"timestamp": "2016-12-01"}]
                ]
            }
          }},
          {
            "$unwind" : "$daily"
          },
          {
            "$match" : {
              "daily.timestamp" : {
                "$lte" : "2016-12-02",
                "$gte" : "2016-12-01"
              }
            }
          },
          {
            "$group" : {
              "impressions" : {
                "$sum" : "$daily.impressions"
              },
              "ad_account_id" : {
                 "$first" : "$ad_account_id"
               },
              "_id" : "$internal_id"
            }
          },
          {
            "$project" : {
              "impressions" : 1,
              "ga_transactions" : 1,
              "ad_account_id" : 1
            }
          }
    }

Nhưng điều này đã gây ra lỗi cho tôi "" FieldPath '2016-12-01' không bắt đầu bằng $". Tò mò rằng chúng ta có thể xử lý việc này bằng tất cả các kỹ thuật khác nhau nào?

Làm cách nào để lọc mảng đối tượng trong MongoDB Compass?

Lọc phần tử từ mảng . Để đạt được mục tiêu của chúng tôi – lọc tài liệu để chỉ hiển thị các trường chúng tôi cần – chúng tôi phải sử dụng toán tử bộ lọc $ cùng với khung tổng hợp. using the $project aggregation stage. To achieve our goal – to filter the document to show only the fields we need – we must use the $filter operator alongside the aggregation framework.

Làm cách nào để khớp giá trị mảng trong MongoDB?

Toán tử $elemMatch khớp với các tài liệu chứa trường mảng có ít nhất một phần tử khớp với tất cả các tiêu chí truy vấn đã chỉ định. Nếu bạn chỉ xác định một điều kiện

Làm cách nào để sử dụng bộ lọc $ trong MongoDB?

Trong trường Bộ lọc, hãy nhập tài liệu bộ lọc. Bạn có thể sử dụng tất cả các toán tử truy vấn MongoDB ngoại trừ toán tử $text và $expr. Ví dụ. Bộ lọc sau chỉ trả về các tài liệu có giá trị tiêu đề là Công viên kỷ Jura. .
Nhấp vào Tìm để chạy truy vấn và xem kết quả cập nhật. bấm vào để phóng to

Làm cách nào để tìm kiếm trong mảng trong MongoDB?

Để truy vấn xem trường mảng có chứa ít nhất một phần tử có giá trị được chỉ định hay không, hãy sử dụng bộ lọc { . Để chỉ định điều kiện cho các phần tử trong trường mảng, hãy sử dụng các toán tử truy vấn trong tài liệu bộ lọc truy vấn. {