MongoDB实战篇:高级查询----$elemMatch与aggregate
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了MongoDB实战篇:高级查询----$elemMatch与aggregate,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5896字,纯文字阅读大概需要9分钟。
内容图文
基本的Find查询将在其他章节示例,本文主要针对于遇到的问题与解决的方法做个记录,希望可以减少遇到这类问题的同胞-_-!
第一部分 需求与问题
1.1 数据结构
1.1.1 插入测试数据
db.hhw.insert({results: [ { item: "a", qty: 26, tags: ["blank", "red"], dim_cm: [ 1, 10 ] }, { item: "a", qty: 27, tags: ["blank", "red"], dim_cm: [ 15, 30 ] }, { item: "a", qty: 28, tags: ["blank", "red"], dim_cm: [ 50, 70 ] }, { item: "b", qty: 27, tags: ["blank", "red"], dim_cm: [ 80, 90 ] } ] });
1.1.2 获取数据, 在此没有?pretty()格式化
> db.hhw.find()
{ "_id" : ObjectId("58b675a556341c2186667dd4"),
"results" : [
{ "item" : "a", "qty" : 26, "tags" : [ "blank", "red" ], "dim_cm" : [ 1, 10 ] },
{ "item" : "a", "qty" : 27, "tags" : [ "blank", "red" ], "dim_cm" : [ 15, 30 ] },
{ "item" : "a", "qty" : 28, "tags" : [ "blank", "red" ], "dim_cm" : [ 50, 70 ] },
{ "item" : "b", "qty" : 27, "tags" : [ "blank", "red" ], "dim_cm" : [ 80, 90 ] }
] }
1.2 需求
需求一: 获取到results中item的值为
a
的结果集合.
第二部分 解决问题
2.1 尝试的方法一 -------- find子句$elemMatch
参考官网V3.4 eleMatch, 大致功能为投影操作符将限制查询返回的数组字段的内容只包含匹配elemMatch条件
的数组元素。其实`$elemMatch专门用于查询数组Field中元素是否满足指定的条件。
> db.hhw.find({
results: { $elemMatch: { item: "a"}}})
#确实是全部数据
{ "_id" : ObjectId("58b675a556341c2186667dd4"),
?"results" : [ { "item" : "a", "qty" : 26, "tags" : [ "blank", "red" ], "dim_cm" : [ 1, 10 ] },
?{ "item" : "a", "qty" : 27, "tags" : [ "blank", "red" ], "dim_cm" : [ 15, 30 ] },
?{ "item" : "a", "qty" : 28, "tags" : [ "blank", "red" ], "dim_cm" : [ 50, 70 ] },
? { "item" : "b", "qty" : 27, "tags" : [ "blank", "red" ], "dim_cm" : [ 80, 90 ] } ] }
按照官网V3.4 eleMatch的实例,一直达不到预期的效果,按照的版本是v3.4.0, 文档参考的也是v3.4.0好奇!
解决的方法,参考了StackOverflow中, find之后的第一个参数设置为{}
, 但是得写上.
> db.hhw.find({}, {
?results: {
? ?$elemMatch: { item: "a"}
? ?}
?})
?#只返回了符合elemMatch的第一条数据
{ "_id" : ObjectId("58b675a556341c2186667dd4"),
?"results" : [ { "item" : "a", "qty" : 26, "tags" : [ "blank", "red" ], "dim_cm" : [ 1, 10 ] } ] }
注意:
1. 数组中元素是内嵌文档。 2. 如果多个元素匹配$elemMatch条件,操作符返回数组中第一个匹配条件的元素。
2.2 既然来了, 就操作一下$elemMatch吧
需求: 要查询 dim_cm
中满足至少存在
一个元素大于等于
10且小于20的
2.3 转到第三部分
第三部分 聚合aggregate
3.1 语法以及参数
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
>$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
$match:用于过滤数据,只输出符合条件的文档。
$match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
$geoNear:输出接近某一地理位置的有序文档。
参数太多,还是直接来上代码
*还是原来的问题,在此使用aggregate来解决
3.2代码如下
> db.hhw.aggregate(
? ?{"$unwind": "$results"},
? ?{"$match": {"results.item": "a"}},
? ?{"$group":{ ? ? ? ?"_id":"$_id", ? ? ? ?"myResult":{ ? ? ? ? ? ?"$push": "$results"
? ? ? ?}
? ? ?}}
)#结果达到预期效果,三个a
{ "_id" : ObjectId("58b675a556341c2186667dd4"), "myResult" : [ { "item" : "a", "qty" : 26, "tags" : [ "blank", "red" ], "dim_cm" : [ 1, 10 ] }, { "item" : "a", "qty" : 27, "tags" : [ "blank", "red" ], "dim_cm" : [ 15, 30 ] }, { "item" : "a", "qty" : 28, "tags" : [ "blank", "red" ], "dim_cm" : [ 50, 70 ] } ] }
3.3 接下来一步步拆分上边的三条语句
3.3.1 $unwind: 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。类似于遍历,前后都有$符号
> db.hhw.aggregate({"$unwind": "$results"}) { "_id" : ObjectId("58b675a556341c2186667dd4"), "results" : { "item" : "a", "qty" : 26, "tags" : [ "blank", "red" ], "dim_cm" : [ 1, 10 ] } } { "_id" : ObjectId("58b675a556341c2186667dd4"), "results" : { "item" : "a", "qty" : 27, "tags" : [ "blank", "red" ], "dim_cm" : [ 15, 30 ] } } { "_id" : ObjectId("58b675a556341c2186667dd4"), "results" : { "item" : "a", "qty" : 28, "tags" : [ "blank", "red" ], "dim_cm" : [ 50, 70 ] } } { "_id" : ObjectId("58b675a556341c2186667dd4"), "results" : { "item" : "b", "qty" : 27, "tags" : [ "blank", "red" ], "dim_cm" : [ 80, 90 ] } }
3.3.3 $match过滤数据
3.3.4 $group将集合中的文档分组,可用于统计结果
上边的例子我们将所有的字段统一返回, 假如此时我们只想返回item
tags
呢?
> db.hhw.aggregate( {"$unwind": "$results"}, {"$match": {"results.item": "a"}}, {"$group":{ "_id":"$_id", "myResult":{ "$push": {"Item": "$results.item", "tags": "$results.tags"} } }} ) { "_id" : ObjectId("58b675a556341c2186667dd4"), "myResult" : [ { "Item" : "a", "tags" : [ "blank", "red" ] }, { "Item" : "a", "tags" : [ "blank", "red" ] }, { "Item" : "a", "tags" : [ "blank", "red" ] } ] }
3.3.5 $project 限定结果集合
此时只有两个字段(_id, results), 只显示results
db.hhw.aggregate( { $project : { _id : 0 , results : 1 , }} ); { "results" : [ { "item" : "a", "qty" : 26, "tags" : [ "blank", "red" ], "dim_cm" : [ 1, 10 ] }, { "item" : "a", "qty" : 27, "tags" : [ "blank", "red" ], "dim_cm" : [ 15, 30 ] }, { "item" : "a", "qty" : 28, "tags" : [ "blank", "red" ], "dim_cm" : [ 50, 70 ] }, { "item" : "b", "qty" : 27, "tags" : [ "blank", "red" ], "dim_cm" : [ 80, 90 ] } ] }
遇到的问题
X.1 在mongoose 中aggregate中match id 时出现错误的解决办法:
Product.aggregate( {"$unwind": "$products"}, // 执行成功 {"$match": {"products.price": 9}}, // 执行失败 {"$match": {"products._id": "58b77e509219010a6eac48ed"}},#下边方法成功 {"$match": {"products._id": new mongoose.Types.ObjectId('58b77e509219010a6eac48ed')}}, function(err, result){ if (err) { console.log(err); }else { res.send(result); } } );
mongoose中有两个地方
定义了ObjectId
,mongoose.schema.Types.ObjectId
和mongoose.Types.ObjectId,在这里只有mongoose.Types.ObjectId才起作用。
内容总结
以上是互联网集市为您收集整理的MongoDB实战篇:高级查询----$elemMatch与aggregate全部内容,希望文章能够帮你解决MongoDB实战篇:高级查询----$elemMatch与aggregate所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。