【问题标题】:mongodb nested object array querymongodb嵌套对象数组查询
【发布时间】:2015-08-09 18:46:19
【问题描述】:

我知道这已经被问了一百万次,但我找不到我的确切场景,所以我们开始吧:

我的数据如下所示:

{
"_id" : ObjectId("55bf22a73d64bd3c495adf3d"),
"_data_type" : "questionnaire",
"title" : "Food quality",
"_namespace" : "questionnaire",
"description" : "tell us your opinion",
"created_time" : ISODate("2015-08-03T08:13:27.874Z"),
"questions" : {
    "sub_id_1" : {
        "o2" : "Bad",
        "o1" : "Good",
        "_namespace" : "questionnaire::question",
        "question" : "How do you rate our food quality"
    },
    "sub_id_2" : {
        "o2" : "Bad",
        "o1" : "Good",
        "_namespace" : "questionnaire::question",
        "question" : "How do you rate the colouring of our dishes "
    },
    "sub_id_3" : {
        "o2" : "I don't care!",
        "o1" : "It is greate",
        "_namespace" : "questionnaire::question",
        "question" : "How do you like our couches"
    }
},
"updated_time" : ISODate("2015-08-03T08:20:37.982Z")
}

我想得到所有“o2”等于“Bad”的问题。

我尝试了以下但没有运气。

> db.questionnaire.find({"questions.$.o2": "Bad"})
> db.questionnaire.find({"questions.o2": "Bad"})

【问题讨论】:

  • 你能告诉我们预期的结果吗?
  • 它想要返回包含一个“questions”数组的所有文档,该数组至少有一个问题为o2 =“Bad”
  • 我不认为这是一个选项!无论如何要解决它?!

标签: javascript mongodb mongodb-query


【解决方案1】:

对于您当前的文档结构,您需要使用 $where 运算符来执行 JavaScript 评估。

db.collection.find(function(){
    for (var key in this.questions) {     
        if (this.questions[key]["o2"] == "Bad")         
            return true; 
    }
})

但是我建议你改变你的文档结构,因为一般是you don't want to use$where。为此,您需要使用Bulk() Api。

var bulk = db.collection.initializeUnorderedBulkOp();
var questions = [];
var subdoc = {};
var count  = 0;

db.collection.find().forEach(function(doc) { 
    for (var key in doc.questions) {     
        subdoc["o2"] = doc.questions[key]["o2"];    
        subdoc["o1"] = doc.questions[key]["o1"];    
        subdoc["_namespace"] = doc.questions[key]["_namespace"]; 
        subdoc["question"] = doc.questions[key]["question"];   
        subdoc["id"] = key;     
        questions.push(subdoc); 
        subdoc = {};
    } 

    bulk.find({ "_id": doc._id }).updateOne({
        "$set": { "questions": questions }});
    count++; 
    if (count % 1000 == 0) {  
        // Execute per 1000 operations and re-init.   
        bulk.execute();    
        bulk = db.collection.initializeUnorderedBulkOp(); 
    } 
})

// Clean up queues
if ( count % 1000 != 0 ) { 
    bulk.execute(); 
}

那么你的文档看起来像这样:

> db.collection.find().pretty()
{
        "_id" : ObjectId("55bf22a73d64bd3c495adf3d"),
        "_data_type" : "questionnaire",
        "title" : "Food quality",
        "_namespace" : "questionnaire",
        "description" : "tell us your opinion",
        "created_time" : ISODate("2015-08-03T08:13:27.874Z"),
        "questions" : [
                {
                        "o2" : "Bad",
                        "o1" : "Good",
                        "_namespace" : "questionnaire::question",
                        "question" : "How do you rate our food quality",
                        "id" : "sub_id_1"
                },
                {
                        "o2" : "Bad",
                        "o1" : "Good",
                        "_namespace" : "questionnaire::question",
                        "question" : "How do you rate the colouring of our dishes ",
                        "id" : "sub_id_2"
                },
                {
                        "o2" : "I don't care!",
                        "o1" : "It is greate",
                        "_namespace" : "questionnaire::question",
                        "question" : "How do you like our couches",
                        "id" : "sub_id_3"
                }
        ],
        "updated_time" : ISODate("2015-08-03T08:20:37.982Z")
}

您的查询变得更简单,并且可以使用索引(如果有)。

db.collection.find({ "questions.o2": "Bad" })

【讨论】:

    猜你喜欢
    • 2012-07-23
    • 2016-09-05
    • 1970-01-01
    • 2021-01-24
    • 1970-01-01
    • 2018-11-01
    • 2019-05-17
    • 2018-09-10
    • 2020-03-28
    相关资源
    最近更新 更多