mongodb $ where查询获取子文档内容

时间:2014-04-03 17:04:47

标签: mongodb mongodb-query aggregation-framework

mongodb查询下面没有返回文档。查询有什么问题?我想指定$where来匹配数组中的元素

[编辑] 以上问题是我的方案的简化版本。我正在使用spring数据mongodb存储库。我想使用@Query注释指定查询。希望$where部分是简单的比较而不是完整的javascript功能。

之类的东西
@Query ( value=" { flag: true, $where: \"this.versions.version == this.defaultVersion \"}", fields = "{'versions' : 1}" )
Foo getDefaultVersion();

如果$where的语法不正确,请提供替代方案。

db.foo.find({
    flag: true,
    $where: "this.versions.version == this.defaultVersion " },
    { 'versions' : 1}
});

收集:

{
    flag: true,
    defaultVersion: "1.0",
    versions: [
        {
            version: "1.0",
            tags: ["abc", "def"]
        },
        {
            version: "1.1",
            tags: ["abc", "def"]
        }
    ]
}

我想要获取"版本"版本数组中的子文档,其匹配版本为defaultVersion属性。

[EDIT2] 我可以使用$ elemMatch缩小范围

db.foo.find({
    flag: true,
    versions: { $elemMatch : { version: '1.0' } } 
    },
    { 'versions' : 1}
});

在上面代替硬编码'1.0',我想指定文档的defaultVersion。不知道我该如何实现它?

2 个答案:

答案 0 :(得分:2)

试试这个:

db.so.find({
    flag: true,
    $where: function () {
        var versions = this.versions; 
        for (var i=0; i<versions.length; i++) {
            if (versions[i].version == this.defaultVersion) return true;
        }
    }
});

<强> [编辑] 杰克编辑了他的问题,说他不想使用JavaScript函数,而是使用简单的表达式。我不认为这是可能的。

答案 1 :(得分:2)

在大多数情况下应避免使用$where运算符,因为无论其他条件可能使用索引选择,它都会调用完整的集合扫描。

此外,您在每个结果文档上调用JavaScript解释器,这将比本机代码慢得多。阅读手册页上的警告,它们是有原因的

如果可能,请尝试使用.aggregate()进行此类比较。在你的情况下,它绝对是更好的选择:

db.foo.aggregate([
    { "$match": { "flag": true } },
    { "$unwind": "$versions" },
    { "$project": {
        "versions": "$versions"
        "same": { "$eq": [ "$versions.version", "$defaultVersion" ] }
    }}
    { "$match": { "same": true } },
    { "$project": {
        "_id": 0,
        "versions": 1
    }}
])

这允许您首先通过&#34;标记&#34;过滤您的查询。条件,然后检查数组的每个成员,以比较两个字段是否相同。

如果需要,您可以将匹配的数组元素回滚到一个有多个匹配的数组中。但我认为这不是你的要求。