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

Mongo - Khớp nơi khóa đối tượng là biến

Với MongoDB 3.4.4, sử dụng khung tổng hợp để truy vấn tài liệu. Điều này có thể thực hiện được với $objectToArray toán tử cho phép bạn ánh xạ các khóa trong trường được xử lý thành một mảng các cặp khóa / giá trị. Danh sách sẽ dễ dàng lọc và lấy (các) khóa phù hợp với bất kỳ điều kiện nào bạn có.

Trong ví dụ sau, đường dẫn tổng hợp bao gồm một trường bổ sung chứa (các) khóa phù hợp với điều kiện có giá trị false ở trên, vì vậy lý tưởng nhất nó sẽ là một mảng:

db.collection.aggregate([
    { "$addFields": {
        "notProcessed": { 
            "$map" : {
                "input": {
                    "$filter": {
                        "input": { "$objectToArray": "$processed" },
                        "as": "el",
                        "cond": { "$not": "$$el.v" }
                    }
                },
                "in": "$$this.k"
            }
        }
    } }
])

cái nào mang lại

{
    "_id" : ObjectId("5501b1648ef0b4eccc41814e"),
    "link" : "xxxxx.jpg",
    "processed" : {
        "320" : true,
        "480" : true,
        "540" : true,
        "720" : true,
        "800" : true,
        "1080" : true,
        "original" : false,
        "iPhone" : true
    },
    "notProcessed" : [ 
        "original"
    ]
}

Giải thích

Bắt đầu với biểu thức lồng nhau

{
    "$filter": {
        "input": { "$objectToArray": "$processed" },
        "as": "el",
        "cond": { "$not": "$$el.v" }
    }
}

đầu vào cho $filter operator { "$objectToArray": "$processed" } sẽ chuyển đổi các khóa trong processed chìa khóa cho mảng này:

[ 
    {
        "k" : "320",
        "v" : true
    }, 
    {
        "k" : "480",
        "v" : true
    }, 
    {
        "k" : "540",
        "v" : true
    }, 
    {
        "k" : "720",
        "v" : true
    }, 
    {
        "k" : "800",
        "v" : true
    }, 
    {
        "k" : "1080",
        "v" : true
    }, 
    {
        "k" : "original",
        "v" : false
    }, 
    {
        "k" : "iPhone",
        "v" : true
    }
]

$filter sẽ lọc mảng ở trên để chỉ có các phần tử đối tượng có v thuộc tính NOT true :

[ 
    {
        "k" : "original",
        "v" : false
    }
]

$map sau đó sẽ trả về một mảng được ánh xạ chỉ với các giá trị

[ { "k" : "original", "v" : false } ] => [ "original" ]

vì vậy bạn kết thúc chỉ với

[ "original" ]

kết quả là.

Với các phiên bản MongoDB cũ hơn, sẽ khá khó khăn để đưa ra các truy vấn đối với các khóa động. Xem xét sửa đổi giản đồ của bạn để tuân theo mô hình tài liệu này, dễ truy vấn hơn:

// this operation changes the schema
var processed = [];
db.collection.find().forEach( function(doc) {
     for(key in doc.processed) {
        if(doc.processed.hasOwnProperty(key)) {
            var item = { key: key, value: doc.processed[key] }
            processed.push(item);            
        }
     }
     doc.processed = processed;
     db.collection.save(doc);
});

// modified schema    

{ 
    "link": "xxxxx.jpg"
    "_id": ObjectId("5501b1648ef0b4eccc41814e"),
    "processed": [
         { "key": "320", "value": true },
         { "key": "480", "value": true },
         { "key": "540", "value": true },
         { "key": "720", "value": true },
         { "key": "800", "value": true },
         { "key": "1080", "value": true },
         { "key": "original", "value": false },
         { "key": "iPhone", "value": true }
    ]
}

Truy vấn tìm kiếm của bạn sẽ đơn giản là

db.collection.find({"processed.value": false});

hoặc sử dụng $map $filter để trả lại các khóa có false giá trị như

db.collection.aggregate([
    { "$project": {
        "link": 1,
        "notProcessed": { 
            "$map" : {
                "input": {
                    "$filter": {
                        "input": "$processed",
                        "as": "el",
                        "cond": { "$not": "$$el.v" }
                    }
                },
                "in": "$$this.k"
            }
        }
    } }
])


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Symfony QueryBuilder trả về con trỏ MongoDB thay vì mảng đối tượng

  2. Truy vấn MongoDB bên trong một mảng lồng nhau

  3. Vấn đề về Node + Mongodb + ISODate + Múi giờ

  4. không thể truy cập các thuộc tính của req.user

  5. MongoDB không sử dụng /etc/mongodb.conf sau khi tôi thay đổi dbpath