mongodb $ where查询以获取子文档内容 [英] mongodb $where query to fetch sub-document content

查看:764
本文介绍了mongodb $ where查询以获取子文档内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下mongodb查询未返回文档.查询出了什么问题?我想指定$where匹配数组中的元素

Below mongodb query is not returning the document. What is wrong with the query? I want to specify $where to match an element in array

上面的问题是我的方案的简化版本.我正在使用spring数据mongodb存储库.我想使用@Query批注指定查询.希望$where部分是简单的比较,而不是完整的javascript函数.像

Above problem is a simplified version of my scenario. I am using a spring data mongodb repository. I want to specify the query using @Query annotation. Was hoping the $where part to be simple comparison and not a full fledged javascript function. something like

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

如果$where的语法不正确,请提出其他建议.

If $where is not the correct syntax, please suggest alternatives.

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属性的版本数组中获取版本"子文档.

I want to fetch the "version" sub-document from versions array which has matching version as defaultVersion property.

,我可以使用$ elemMatch将其范围缩小

I was able to narrow it down using $elemMatch

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

在上面代替硬编码的'1.0',我想指定文档的defaultVersion.不确定如何实现?

In the above in place of hardcoded '1.0', I would like to specify the defaultVersion of the document. Not sure how do I achieve it?

推荐答案

使用 $where 运算符,因为无论其他什么条件可能使用索引选择,该运算符都将调用完全集合扫描.

Using the $where operator should be avoided in most cases as it is both going to invoke a full collection scan regardless of what other conditions could possibly use an index selection.

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

In addition you are invoking the JavaScript interpreter over each result document, which is going to be considerably slower than native code. Read the warnings on the manual page, they are there for a reason

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

Where possible, please try to use .aggregate() for this type of comparison instead. In your case it is definitely the better option:

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

这使您可以首先通过标志"条件过滤查询,然后检查数组的每个成员以比较两个字段是否相同.

This allows you to first filter your query by the "flag" condition and then inspect each member of the array to compare if the two fields are the same.

如果有必要,您可以将匹配的数组元素回滚到存在多个匹配项的数组中.但是我不认为这是您的要求.

If necessary you can then roll back the matched array elements into an array where there is more than one match. But I don't think that is your requirement.

这篇关于mongodb $ where查询以获取子文档内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆