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

Dự án lọc thuộc tính trong mảng lồng nhau thứ hai

Vì yêu cầu của bạn là chỉ "chiếu" tài liệu nên trường bị che, có, khung tổng hợp là một công cụ để thực hiện việc này. Tuy nhiên, bạn phải mất một chút thời gian để tìm hiểu quy trình khi giải nén các mảng và tạo lại.

Vì vậy, những gì bạn muốn là cái này:

db.collection.aggregate([
    { "$unwind": "$questions" },
    { "$unwind": "$questions.answers" },
    { "$group": { 
        "_id": {
            "_id": "$_id",
            "name": "$name",
            "description": "$description",
            "qid": "$questions._id",
            "question": "$questions.question"
        },
        "answers": {
            "$push": {
                "_id": "$questions.answers._id",
                "answer": "$questions.answers.answer"
            }
        }
    }},
    { "$project": {
        "questions": {
            "_id": "$_id.qid",
            "question": "$_id.question",
            "answers": "$answers"
        }
    }},
    { "$sort": { "_id": 1, "questions._id": 1 } },
    { "$group": {
        "_id": "$_id._id",
        "name": { "$first": "$_id.name" },
        "description": { "$first": "$_id.description" },
        "questions": { "$push": "$questions" }
    }}
])

Nhưng thực sự, nếu bạn có phiên bản MongoDB 2.6 trở lên thì bạn không cần phải $ unwind $ group kết quả trở lại cùng nhau để bỏ qua trường đó. Giờ đây, bạn có thể thực hiện việc này bằng cách sử dụng $ project $ map toán tử hoạt động với mảng:

db.collection.aggregate([
    { "$project": {
        "name": 1,
        "description": 1,
        "questions": {
            "$map": {
                "input": "$questions",
                "as": "q",
                "in": {
                    "$ifNull": [
                        { 
                            "_id": "$$q._id",
                            "question": "$$q.question",
                            "answers": {
                                "$map": {
                                    "input": "$$q.answers",
                                    "as": "el",
                                    "in": {
                                        "$ifNull": [
                                            { "_id": "$$el._id", "answer": "$$el.answer" },
                                            false
                                        ]
                                    }
                                }
                            }
                        },
                        false
                    ]
                }
            }
        }
    }}
])

Xin lỗi vì phần thụt lề cuộn ra khỏi trang ở đó một chút, nhưng so sánh thì vẫn dễ đọc hơn.

$ map đầu tiên xử lý mảng câu hỏi tại chỗ và nguồn cấp dữ liệu cho $ map trả về các tài liệu mảng câu trả lời bên trong mà không có trường "isCorrectAnswer". Nó sử dụng các biến của chính nó để đại diện cho các phần tử và việc sử dụng $ ifNull trong đó chỉ là vì phần "trong" của $ map nhà điều hành dự kiến ​​đánh giá một điều kiện trên mỗi phần tử đó.

Nhìn chung, nhanh hơn một chút, vì bạn không phải đi qua $ unwind $ group hoạt động chỉ để loại bỏ trường. Vì vậy, nó thực sự chỉ trở thành "dự báo" mà bạn có thể mong đợi.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Làm thế nào để khởi tạo MongoClient một lần trong Spring Boot và sử dụng các phương thức của nó?

  2. Laravel - Mongodb [jenssegers / laravel-mongodb] - Trình tạo lược đồ

  3. MongoDB và DynamoDB:Những điều bạn cần biết

  4. Làm cách nào để tham chiếu một lược đồ khác trong lược đồ Mongoose của tôi?

  5. Xem hơn 20 tài liệu gần đây nhất trong MongoDB Compass từ Schema