MongoDB查询返回仅在预定义集合中具有键的文档

时间:2016-09-05 12:29:02

标签: mongodb

MongoDB查询语言允许使用int main(int argc, char *argv[]) { std::vector<char> memory_buffer_char; std::vector<int> memory_buffer_int; std::string memory_buffer_str; Foo foo{"a_string"}; foo.serialize(std::back_inserter(memory_buffer_char)); foo.serialize(std::back_inserter(memory_buffer_int)); foo.serialize(std::back_inserter(memory_buffer_str)); return 0; } 运算符根据给定字段的存在与否来过滤文档。

有没有一种方法,使用MongoDB语法,并给定$exists个允许字段,以排除结果中不包含K字段的文档,但是:

  • 事先不知道可以遇到哪些额外字段(K之外)
  • 不使用JavaScript,即K运算符?

示例:

$where

使用集合{ "Some field" : "foo" } { "Some field" : "bar", "Some other field" : "foobar" } ,只返回第一个文档。

请注意,不要将此与投影相混淆,投影会返回两个文档,但会删除额外的字段。

2 个答案:

答案 0 :(得分:1)

我不确定MongoDB是否支持开箱即用的此类操作,但您可以在mapReduce的帮助下实现此目的。

假设您的样本数据集;

// Variable for map
var map = function () {
    var isAcceptable = true;
    Object.keys(this).forEach(function (key) {
        if (key != "_id" && white_list.indexOf(key) == -1) {
            isAcceptable = false;
        }
    });

    if (isAcceptable == true) {
        emit(1, this);
    }
};

// Variable for reduce
var reduce = function (key, values) {
    return values;
};

db.collection.mapReduce(
    map,
    reduce,
    {
        scope: {"white_list": ["Some field"]},
        out: {"inline": 1}
    }
);

将返回:

{ 
    "results" : [
        {
            "_id" : 1, 
            "value" : {
                "_id" : ObjectId("57cd7503e55de957c62fb9c8"), 
                "Some field" : "foo"
            }
        }
    ], 
    "timeMillis" : 13, 
    "counts" : {
        "input" : 2, 
        "emit" : 1, 
        "reduce" : 0, 
        "output" : 1
    }, 
    "ok" : 1
}

所需结果将在退回文档的results.values中。但是,请记住MongoDB mapReduce的限制和BSON文档的最大大小。

答案 1 :(得分:0)

给定一组已知字段K,您可以构建一个查询,将该集作为输入,并使用 $exists 运算符和相应字段进行查询投影。举个例子,假设您在测试集合中有以下文档

db.test.insert({ "fieldX": "foo", "fieldY": "bar", "fieldZ": 1 })
db.test.insert({ "fieldX": "123", "fieldY": "bar", "fieldZ": 2 })
db.test.insert({ "fieldY": "abc", "fieldZ": 3 })
db.test.insert({ "fieldX": "xyz", "fieldZ": 4 })
db.test.insert({ "fieldZ": 5 })

然后,您可以从输入集Q构建查询P和投影K,如下所示:

var K = [ "fieldX", "fieldZ" ];  

var or = K.map(function(field) { 
    var obj = {};
    obj[field] = { "$exists": true };
    return obj;
});

var P = K.reduce(function(doc, field) { 
    doc[field] = 1;
    return doc;
}, {} );

var Q = { "$or": or };

db.test.find(Q, P);

示例输出:

/* 1 */
{
    "_id" : ObjectId("57cd78322c241f5870c82b7d"),
    "fieldX" : "foo",
    "fieldZ" : 1
}

/* 2 */
{
    "_id" : ObjectId("57cd78332c241f5870c82b7e"),
    "fieldX" : "123",
    "fieldZ" : 2
}

/* 3 */
{
    "_id" : ObjectId("57cd78332c241f5870c82b7f"),
    "fieldZ" : 3
}

/* 4 */
{
    "_id" : ObjectId("57cd78332c241f5870c82b80"),
    "fieldX" : "xyz",
    "fieldZ" : 4
}

/* 5 */
{
    "_id" : ObjectId("57cd78332c241f5870c82b81"),
    "fieldZ" : 5
}