查询数组大小大于1的文档
我有一个 MongoDB 集合,其中包含以下格式的文档:
{
"_id" : ObjectId("4e8ae86d08101908e1000001"),
"name" : ["Name"],
"zipcode" : ["2223"]
}
{
"_id" : ObjectId("4e8ae86d08101908e1000002"),
"name" : ["Another ", "Name"],
"zipcode" : ["2224"]
}
我当前可以获得与特定数组大小匹配的文档:
db.accommodations.find({ name : { $size : 2 }})
这会正确返回 name
数组中包含 2 个元素的文档。但是,我无法执行 $gt
命令来返回 name
字段的数组大小大于 2 的
db.accommodations.find({ name : { $size: { $gt : 1 } }})
所有文档:How can I select all document with a name
数组的大小大于一(最好不必修改当前数据结构)?
I have a MongoDB collection with documents in the following format:
{
"_id" : ObjectId("4e8ae86d08101908e1000001"),
"name" : ["Name"],
"zipcode" : ["2223"]
}
{
"_id" : ObjectId("4e8ae86d08101908e1000002"),
"name" : ["Another ", "Name"],
"zipcode" : ["2224"]
}
I can currently get documents that match a specific array size:
db.accommodations.find({ name : { $size : 2 }})
This correctly returns the documents with 2 elements in the name
array. However, I can't do a $gt
command to return all documents where the name
field has an array size of greater than 2:
db.accommodations.find({ name : { $size: { $gt : 1 } }})
How can I select all documents with a name
array of a size greater than one (preferably without having to modify the current data structure)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
现在,您可以在查询对象键中使用数字数组索引(从 0 开始),在 MongoDB 2.2+ 中,有一种更有效的方法可以做到这一点。
您可以通过使用部分过滤表达式的索引来支持此查询(需要 3.2+):
There's a more efficient way to do this in MongoDB 2.2+ now that you can use numeric array indexes (0 based) in query object keys.
You can support this query with an index that uses a partial filter expression (requires 3.2+):
更新:
对于 mongodb 版本2.2+,更有效的方法由 @JohnnyHK 在另一个 答案。
使用$where
db.accommodations.find( { $where: "this.name.length > 1" } );
但...
创建额外字段
NamesArrayLength
,使用名称数组长度更新它,然后在查询中使用:db.accommodations.find({"NamesArrayLength": {$gt: 1} });
这将是更好的解决方案,并且工作速度更快(您可以在其上创建索引)。
Update:
For mongodb versions 2.2+ more efficient way to do this described by @JohnnyHK in another answer.
Using $where
db.accommodations.find( { $where: "this.name.length > 1" } );
But...
Create extra field
NamesArrayLength
, update it with names array length and then use in queries:db.accommodations.find({"NamesArrayLength": {$gt: 1} });
It will be better solution, and will work much faster (you can create index on it).
我相信这是回答您的问题最快的查询,因为它不使用解释的
$where
子句 - 它使用$size
数组运算符 和$exists
元素运算符 与$nor
逻辑运算符它的意思是“除了那些没有一个名称(不存在或空数组)或只有一个名称。”
测试:
I believe this is the fastest query that answers your question, because it doesn't use an interpreted
$where
clause -- it uses the$size
array operator and the$exists
element operator combined with$nor
logical operatorIt means "all documents except those without a name (either non existant or empty array) or with just one name."
Test:
您也可以使用聚合:
// 将“size_of_name”添加到运输文档并使用它来过滤名称的大小
You can use aggregate, too:
// you add "size_of_name" to transit document and use it to filter the size of the name
您可以使用 $expr (3.6 mongo 版本运算符)来使用聚合常规查询中的函数。
比较
查询运算符
与聚合比较运算符
。You can use $expr ( 3.6 mongo version operator ) to use aggregation functions in regular query.
Compare
query operators
vsaggregation comparison operators
.尝试执行以下操作:
1 是数字,如果要获取大于 50 的记录,则执行 ArrayName.50
谢谢。
Try to do something like this:
1 is number, if you want to fetch record greater than 50 then do ArrayName.50
Thanks.
MongoDB 3.6 包含 $expr
https://docs.mongodb.com/manual/reference/operator/query/ expr/
您可以使用 $expr 来计算 $match 或 find 中的表达式。
或找到
MongoDB 3.6 include $expr
https://docs.mongodb.com/manual/reference/operator/query/expr/
You can use $expr in order to evaluate an expression inside a $match, or find.
or find
虽然上面的答案都有效,但您最初尝试做的是正确的方法,但是您只是向后使用了语法(切换“$size”和“$gt”)..
正确:
Although the above answers all work, What you originally tried to do was the correct way, however you just have the syntax backwards (switch "$size" and "$gt")..
Correct:
以上都不适合我。这个人做到了,所以我分享它:
None of the above worked for me. This one did so I'm sharing it:
我找到了这个解决方案,查找数组字段大于特定长度的项目
第一个 $match 聚合使用一个对所有文档都适用的参数。没有它,我会得到一个错误异常
I found this solution, to find items with an array field greater than certain length
The first $match aggregate uses an argument that's true for all the documents. Without it, I would get an error exception
您可以通过 MongoDB 聚合来完成该任务:
You can MongoDB aggregation to do the task:
这对你有用
this will work for you
这也适用于指南针。这是我在没有索引的情况下尝试过的最快的。
This will work in Compass also. This is the fastest of all i have tried without indexing.
你可以使用 $expr 来覆盖这个
you can use $expr to cover this
这对我有用:
技巧是在检查长度之前先检查该值是否存在。
我不断收到错误:
那是因为并非所有文档都有 name 字段(或者您称之为的任何字段,请替换)
name
与您感兴趣的数组,例如scores)。不幸的是,这个错误非常模糊,在意识到这是问题所在之前,我尝试了很多其他方法。
注意:我使用的是 MongoDB (Atlas) v6.0.10
This worked for me:
The trick was the check for if the value existed first before checking for the length.
I kept getting an error:
That's because not all the documents had a name field (or whatever field you call it, replace
name
with the array you are interested in, e.g scores).Unfortunately the error was very vague and I tried a whole bunch of other things before realising this was the issue.
Note: I'm using MongoDB (Atlas) v6.0.10