mongoDB 中的字符串字段值长度 [英] String field value length in mongoDB
问题描述
该字段的数据类型是字符串.我想获取字段名称字符长度大于40的数据.
The data type of the field is String. I would like to fetch the data where character length of field name is greater than 40.
我尝试了这些查询,但返回错误.1.
I tried these queries but returning error. 1.
db.usercollection.find(
{$where: "(this.name.length > 40)"}
).limit(2);
output :error: {
"$err" : "TypeError: Cannot read property 'length' of undefined near '40)' ",
"code" : 16722
}
这适用于 2.4.9 但我的版本是 2.6.5
this is working in 2.4.9 But my version is 2.6.5
推荐答案
对于 MongoDB 3.6 及更新版本:
$expr
运算符允许在查询语言中使用聚合表达式,因此您可以利用 $strLenCP
操作符检查字符串的长度如下:
The $expr
operator allows the use of aggregation expressions within the query language, thus you can leverage the use of $strLenCP
operator to check the length of the string as follows:
db.usercollection.find({
"name": { "$exists": true },
"$expr": { "$gt": [ { "$strLenCP": "$name" }, 40 ] }
})
<小时>
对于 MongoDB 3.4 及更新版本:
您还可以将聚合框架与 $redact
管道运算符,允许您使用 $cond
运算符并使用特殊操作 $$KEEP
以保持" 逻辑条件为真的文档或 $$PRUNE
以删除"条件为假的文档.
You can also use the aggregation framework with the $redact
pipeline operator that allows you to proccess the logical condition with the $cond
operator and uses the special operations $$KEEP
to "keep" the document where the logical condition is true or $$PRUNE
to "remove" the document where the condition was false.
此操作类似于具有 $project
管道选择集合中的字段并创建一个新字段,该字段保存逻辑条件查询的结果,然后是后续的$match
,除了$redact
使用更高效的单个管道阶段.
This operation is similar to having a $project
pipeline that selects the fields in the collection and creates a new field that holds the result from the logical condition query and then a subsequent $match
, except that $redact
uses a single pipeline stage which is more efficient.
至于逻辑条件,有String Aggregation Operators您可以使用 $strLenCP
运算符来检查字符串的长度.如果长度是 $gt
一个指定的值,那么这是一个真正的匹配并且文档被保留".否则它会被修剪"并丢弃.
As for the logical condition, there are String Aggregation Operators that you can use $strLenCP
operator to check the length of the string. If the length is $gt
a specified value, then this is a true match and the document is "kept". Otherwise it is "pruned" and discarded.
考虑运行以下聚合操作来演示上述概念:
Consider running the following aggregate operation which demonstrates the above concept:
db.usercollection.aggregate([
{ "$match": { "name": { "$exists": true } } },
{
"$redact": {
"$cond": [
{ "$gt": [ { "$strLenCP": "$name" }, 40] },
"$$KEEP",
"$$PRUNE"
]
}
},
{ "$limit": 2 }
])
<小时>
如果使用 $where
,尝试不带括号的查询:
If using $where
, try your query without the enclosing brackets:
db.usercollection.find({$where: "this.name.length > 40"}).limit(2);
更好的查询是检查字段是否存在,然后检查长度:
A better query would be to to check for the field's existence and then check the length:
db.usercollection.find({name: {$type: 2}, $where: "this.name.length > 40"}).limit(2);
或:
db.usercollection.find({name: {$exists: true}, $where: "this.name.length >
40"}).limit(2);
MongoDB 评估非$where
$where
表达式和非$where
查询语句可能使用索引.更好的性能是将字符串的长度存储为另一个字段,然后您可以对其进行索引或搜索;应用 $where
相比之下会慢得多.建议使用 JavaScript 表达式和 $where
运算符作为您无法以任何其他方式构建数据时的最后手段,或者当您处理数据的小子集.
MongoDB evaluates non-$where
query operations before $where
expressions and non-$where
query statements may use an index. A much better performance is to store the length of the string as another field and then you can index or search on it; applying $where
will be much slower compared to that. It's recommended to use JavaScript expressions and the $where
operator as a last resort when you can't structure the data in any other way, or when you are dealing with a
small subset of data.
一种不同且更快的方法,避免使用 $where
运算符是 $regex
运算符.考虑以下搜索
A different and faster approach that avoids the use of the $where
operator is the $regex
operator. Consider the following pattern which searches for
db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2);
注意 - 来自 文档:
Note - From the docs:
如果该字段存在索引,则 MongoDB 匹配正则针对索引中的值的表达式,这可能比 a集合扫描.如果常规的可以进行进一步的优化表达式是一个前缀表达式",这意味着所有潜在的匹配以相同的字符串开始.这允许 MongoDB 构建一个来自该前缀的范围",并且只匹配来自位于该范围内的索引.
If an index exists for the field, then MongoDB matches the regular expression against the values in the index, which can be faster than a collection scan. Further optimization can occur if the regular expression is a "prefix expression", which means that all potential matches start with the same string. This allows MongoDB to construct a "range" from that prefix and only match against those values from the index that fall within that range.
一个正则表达式是一个前缀表达式",如果它以脱字符 (^)
或左锚 (A)
,后跟一串简单的符号.例如,正则表达式 /^abc.*/
将被优化为仅与索引中以 abc
开头的值匹配.
A regular expression is a "prefix expression" if it starts with a
caret (^)
or a left anchor (A)
, followed by a string of simple
symbols. For example, the regex /^abc.*/
will be optimized by
matching only against the values from the index that start with abc
.
另外,虽然 /^a/,/^a.*/,
和 /^a.*$/
匹配等价弦,它们具有不同的性能特征.所有这些如果存在适当的索引,则表达式使用索引;然而,/^a.*/
和 /^a.*$/
比较慢./^a/
可以停止扫描匹配前缀.
Additionally, while /^a/, /^a.*/,
and /^a.*$/
match equivalent
strings, they have different performance characteristics. All of these
expressions use an index if an appropriate index exists; however,
/^a.*/
, and /^a.*$/
are slower. /^a/
can stop scanning after
matching the prefix.
这篇关于mongoDB 中的字符串字段值长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!