mongodb $ where查询以获取子文档内容 [英] mongodb $where query to fetch sub-document content
问题描述
以下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屋!