MongoDB如何对数组中的元素进行查询详解_MongoDB_脚

作者:计算机专家

MongoDB中根据数组子元素进行匹配,有两种方式。

{"author" : "zhangsan","score" : 3,"comment" : "shafa!"},

{ "qList.qid": 1, "qList.reorderFlag": 0}

options(使用options(使用regex )

document1 如下:

"$mod"

总结

查询出amount键值为16或者50的文档:

可以看到, 其执行结果是, 对数组进行匹配, 其中需要有子元素 满足 "qList.qid": 1, 还需要有子元素 满足 "qList.qid": 1, , 适合进行单个条件的匹配。

db.inventory.find( { amount:50}} )

“[数组名].[子元素字段名]” 的方式匹配的主体为 “[数组名]”, 适用于单个条件,如果是多个条件, 则变成数组子元素之间的“或”运算。

//查询name键值以“4”结尾的文档db.inventory.find( { name: /.4/i } );

查询数组内同一条记录同时满足2个条件的语句:

_id:2,

{ "_id" : "123", "name" : "人文医学", "qList" : [ { "qid" : 1, "content" : "医学伦理学的公正原则", "reorderFlag" : 1 }, { "qid" : 2, "content" : "制定有关人体实验的基本原则", "reorderFlag" : 0 } ]}

;)

找出数组中, 具有 qid=1并且reorderFlag=0的记录

图片 1

假设某个集合内有2条数据:

查询集合中tags键值包含有3个元素的数组的所有文档:

找出数组中, qid=1 或者 reorderFlag=0的记录

语法: { field: { $mod: [ divisor, remainder ]} }

使用 “[数组名].[子元素字段名]” 的方式进行匹配。 使用 “[数组名]” $elemMatch { [子元素字段名] }的方式。

查询集合中 amount 键值为 4 的 0 次模数的所有文档,例如 amount 值等于 16 的文档

{ "_id" : "124", "name" : "人文医学2", "qList" : [ { "qid" : 1, "content" : "医学伦理学的公正原则", "reorderFlag" : 0 }, { "qid" : 2, "content" : "制定有关人体实验的基本原则", "reorderFlag" : 1 } ]}

1.1 集合查询方法 find()

数组整体能满足以下2个条件:

$elemMatch可以指定多个字段的限定条件,下面的操作将查询邮政编码键值是63109的所有文档。$elemMatch操作符将返回 students数组中的第一个匹配条件(内嵌文档的school键且值为102且age键值大于10)的元素。

请看示例:

语法: { field: { $not: { } } }

{ "qList": { $elemMatch: { "qid": 1, "reorderFlag": 0} } }

{ "_id" : "124", "name" : "人文医学2", "qList" : [ { "qid" : NumberInt, "content" : "医学伦理学的公正原则", "reorderFlag" : NumberInt }, { "qid" : NumberInt, "content" : "制定有关人体实验的基本原则", "reorderFlag" : NumberInt } ]}

"$not"

前言

下面的操作将查询邮政编码键值是63109的所有文档。$elemMatch操作符将返回students数组中的第一个匹配条件(内嵌文档的school键且值为102)的元素。

可以看到, 其执行结果是, 对数组内的每一个子元素, 执行 $elemMatch 匹配, 可以进行多个条件的匹配。

;)

如果是单个条件匹配, 则以下方式结果是一样的。

{ name:"jess", school: 102, age: 11},

MongoDB是文档型数据库,每个文档表示数据的一项记录。相比关系型DB的row只能使用简单的数据类型,doc能够使用复杂的数据类型:内嵌doc,数组。MongoDB的数组是一系列元素的集合,使用中括号 [] 表示数组,例如:[1,2,3]的元素是整数值,[{name:"t5"}, {name:"t7"}],[ {name:"t5", age:21}, {name:"t7", age:22} ]的元素是doc。

>

{ "qList.qid": 1}

{ "qList": { $elemMatch: { "qid": 1} } }

projection    文档  可选.使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略).

查询的结果都是2条记录。

查询返回了所有的文档!

在MongoDB中,数组元素允许重复,元素的位置是固定的。如果两个数组相等,那么这两个数组的元素和及其位置都相同。

db.inventory.find( { amount: { $in: [ 16, 50 ] } } )

执行的主体是 qList, 要求: 有某些子元素满足 qid=1, 也要有某些子元素满足 reorderFlag=0`。

elemMatch投影操作符将限制查询返回的数组字段的内容只包含匹配elemMatch投影操作符将限制查询返回的数组字段的内容只包含匹配elemMatch条件的数组元素。

不同点在于所匹配的主体不同。

//查询不存在qty字段的文档(所有文档)db.inventory.find( { qty: { $exists:false} })//查询amount字段存在,且值不等于16和58的文档db.inventory.find( { amount: { $exists:true, $nin: [ 16, 58 ] } } )

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

{ name:"achilles", school: 100, age: 8},

{ "_id" : "123", "name" : "人文医学", "qList" : [ { "qid" : NumberInt, "content" : "医学伦理学的公正原则", "reorderFlag" : NumberInt }, { "qid" : NumberInt, "content" : "制定有关人体实验的基本原则", "reorderFlag" : NumberInt } ]}{ "_id" : "124", "name" : "人文医学2", "qList" : [ { "qid" : NumberInt, "content" : "医学伦理学的公正原则", "reorderFlag" : NumberInt }, { "qid" : NumberInt, "content" : "制定有关人体实验的基本原则", "reorderFlag" : NumberInt } ]}

上面的结果不是我们期望的,下面使用“$elemMatch”操作符即可将一组条件限定到数组中单条文档的匹配上:

document2 如下:

下面我们将配合查询操作符来执行复杂的查询操作,比如元素查询、 逻辑查询 、比较查询操作。

图片 2

>

文档"{"name":"t1","amount":16,"tags":[ "school", "book", "bag", "headphone", "appliances" ]}",tags键值数组包含四个元素,所以不匹配查询条件。查询结果:

}

图片 3

}returnfalse;

我们可以使用正则表达式对象或者$regex操作符来执行正则匹配:

如果该字段的值为null,$exists的值为true会返回该条文档,false则不返回。

;)

若是文档中不存在表达式中指定的键,表达式值为false; false nor false 等于 true,所以查询结果返回集合中所有文档:

"$nor"

"$and"、"$nor"、"$not"、"$or"、"$exists"、"$mod"、"$regex"、"$where"、"$slice"、"[$elemMatch]()"

;)

语法:{field: {$size: value} }

查询结果:

> db.blogs.find({"comment.author":"zhangsan", "comment.score":{"$gte":4}});

图片 4

//选择comments的数组键值中前五个元素。db.posts.find( {}, { comments: { $slice: 5} } );//选择comments的数组键值中后五个元素。db.posts.find( {}, { comments: { $slice: -5 } } );

图片 5

"$or"

查询内嵌文档

语法: { $or: [ { }, { }, ... , { } ] }

图片 6

{"name":"lilei","age":24,"sex":null}//返回文档中存在sex键,且值为null的文档db.users.find({sex:{$in:[null],$exists:true}})//返回文档中存在birthday键,且值为null的文档//文档没有birthday键,所以结果为空db.users.find({birthday:{$in:[null],$exists:true}})

{ name:"ajax", school: 100, age: 7},

"$in"

_id等于3 和4的文档,因为students数组中没有元素匹配的$elemMatch条件,查询结果不包含“ students”字段。

> db.users.find({}, {"name":1,"age":1})

图片 7

]

> db.inventory.find({"tags.1":"school"})

//选择comments的数组键值中跳过前20项之后前10项元素db.posts.find( {}, { comments: { $slice: [ 20, 10] } } );//选择comments的数组键值中倒数第20项起前10项元素db.posts.find( {}, { comments: { $slice: [ -20, 10 ] } } );

//查询结果是相同的,匹配amount键值等于50的文档db.inventory.find( { amount: {$in:[50]}} )

_id:1,

匹配键值等于指定数组中任意值的文档。类似sql中in.

students: [

查询amount键值不大于50(即小于等于50)的文档数据

图片 8

;)

语法: { field: { $all: [ , ... ] }

查询条件中的键gty,文档中都不存在无法匹配表示,所以返回集合所有文档数据。

_id为1的文档,students数组包含多个元素中存在school键且值为102的元素,$elemMatch只返回一个匹配条件的元素。

査询文档可以包含点,来表达“深入内嵌文档内部”的意思,点表示法也是待插入的文档不能包含的原因。当内嵌文档变得复杂后,如键的值为内嵌文档的数组,内嵌文档的匹配需要些许技巧,例如使用$elemMatch操作符。

图片 9

}

我们想查询评论中用户“zhangsan”是否有评分超过4分的评论内容,但我们利用“点表示法”直接写是有问题的,这条查询条件和数组中不同的文档进行了匹配!

运行结果:

;)

>

db.school.find( { zipcode: 63109 },{ students: { $elemMatch: { school: 102, age: { $gt: 10} } } } );

操作符功能强大而且灵活,他可以使用任意的JavaScript作为查询的一部分,包含JavaScript表达式的字符串或者JavaScript函数。

查询name键值不为“t1”,amount键值不小于50的文档:

{"name":"t1","amount":16,"tags":[ "school", "book", "bag", "headphone", "appliances" ]}

db.inventory.find( { name: { $regex:'.4', $options: 'i' } } );

下面介绍指定一个数组作为参数。数组参数使用[ skip , limit ]格式,其中第一个值表示在数组中跳过的项目数,第二个值表示返回的项目数。

_id为3中的文档,因为students数组中元素无法匹配$elemMatch条件,所以查询结果不包含"students"字段。

我们使用下面的比较操作符"$gt" 、"$gte"、 "$lt"、 "$lte"(分别对应">"、 ">=" 、"<" 、"<="),组合起来进行范围的查找。例如查询年龄为16-18岁(包含16但不含18)的用户:

;)

{"name":"xiaohong","age":22,"sex":"female"}

find的第一个参数是查询条件,其形式也是一个文档,决定了要返回哪些文档,空的査询文档{}会匹配集合的全部内容。要是不指定査询文档,默认就是{},如同SQL中"SELECT * FROM TABLENAME"语句。

db.inventory.find( { tags: { $all: [ "appliances", "school", "book" ] } } )

我们可以通过find 的第二个参数来指定返回的键。

图片 10

> db.profile.find({ name : { first : "Barack", last : "Obama" } });{ "_id" : ObjectId("51d7b0d436332e1a5f7299d6"), "name" : { "first" : Barack", "last" : "Obama" } }

运行截图:

我们也可以运行如下语句:

{

执行逻辑OR运算,指定一个至少包含两个表达式的数组,选择出至少满足数组中一条表达式的文档。

查询集合中amount的键值大于50或者name的键值为“t1”的文档:

{ name:"barney", school: 102, age: 7},

db.inventory.find( { amount:50}} )

精确匹配日期要精确到毫秒,然而我们通常只是想得到关于一天、一周或者是一个月的数据,我们可以使用"gt"、"gt"、"lt"进行范围査询。例如,要査找在1990年1月1日出生的用户:

匹配那些指定键的键值中包含数组,而且该数组包含条件指定数组的所有元素的文档,数组中元素顺序不影响查询结果。

//向集合中插入一条amount键值为null的文档{"name":"t4","amount":null,"tags":[ "bag", "school", "book"]}//0条数据db.inventory.find( { amount: { $exists:false} } )//所有的数据db.inventory.find( { amount: { $exists:true} } )

"$gt" 、"$gte"、 "$lt"、 "$lte"、"null查询"、"$all"、"$size"、"$in"、"$nin"、

该查询将匹配tags键值包含如下任意数组的所有文档:

db.inventory.find( { $or: [ { amount: { $gt: 50 } }, { name: "t1" } ] } )

语法: { field: { $exists: } }

图片 11

//mongo dbdb.user.find({age:28,sex:"male"})//Linq to sqldbContext.user.select(p=>p.age==28&&p.sex=="male")//SQLSELECT * FROM user WHERE age=28AND sex="male"

{ name:"jeff", school: 108, age: 15}

要是想查询数组指定位置的元素,则需使用key.index语法指定下标,例如下面查询出tags键值数组中第2个元素为"school"的文档:

语法:db.collection.find( { field: value }, { array: {$slice: count } } );

db.school.find( { zipcode: 63109 },{ students: { $elemMatch: { school: 102 } } } );

//将返回集合中所有文档db.collection.find()//或者db.collection.find({})

若find不指定第二个参数,查询操作默认返回查询文档中所有键值。像SQL中我们可以指定查询返回字段一样 ,mongo中也可以指定返回的键,这样我们就可以避免查询无用键值查询所消耗的资源、会节省传输的数据量和内存消耗。

推荐采用针对键/值对查询,通过点表示法来精确表示内嵌文档的键:

>db.user.find( { age: { $gte:16,$lt:18} }

查询文档有两种方式,一种是完全匹查询,另一种是针对键/值对查询。

//JavaScrip字符串形式db.fruit.find( { $where: "this.banana == this.peach"} )

图片 12

>db.profile.find()

语法: { $and: [ { }, { } , ... , { } ] }

{"content" : ".....","comment": [

;)

如果$exists的值为true,选择存在该字段的文档;若值为false则选择不包含该字段的文档(我们上面在查询键值为null的文档时使用"$exists"判定集合中文档是否包含该键)。

//插入两条数据db.fruit.insert({"apple":1, "banana": 4, "peach" : 4})

}

$slice操作符控制查询返回的数组中元素的个数。

查询name键值为“t1”,amount键值小于50的文档:

"$size"

语法: { $nor: [ { }, { }, ... { } ] }

db.collection.find()查询集合中文档并返回结果为游标的文档集合。

注意:我们尽量避免使用"Where"査询,因为它们在速度上要比常规査询慢很多。每个文档都要从BSON转换成JavaScript对象,然后通过"Where"査询,因为它们在速度上要比常规査询慢很多。每个文档都要从BSON转换成JavaScript对象,然后通过"where"的表达式来运行;同样还不能利用索引。

students: [

在第二个参数中,指定键名且值为1或者true则是查询结果中显示的键;若值为0或者false,则为不显示键。文档中的键若在参数中没有指定,查询结果中将不会显示(_id例外)。这样我们就可以灵活显示声明来指定返回的键。

db.inventory.find( { amount: { $mod: [ 4, 0 ] } } )

内嵌文档的完全匹配查询和数组的完全匹配查询一样,内嵌文档内键值对的数量,顺序都必须一致才会匹配:

下面先向集合inventory插入3条数据(下面的演示基于此数据),文档内容如下:

查询操作

键值为null查询操作

执行逻辑NOR运算,指定一个至少包含两个表达式的数组,选择出都不满足该数组中所有表达式的文档。

;)

图片 13

我们可以使用"$ne"来进行"不相等"操作。例如查询年龄不为18岁的用户:

文档中键值类型不是数组,也可以使用$all操作符进行查询操作,如下例所示"$in"对应的数组只有一个值,那么和直接匹配这个值效果是一样的。

文档中键值类型不是数组,也可以使用$all操作符进行查询操作,如下例所示"$all"对应的数组只有一个值,那么和直接匹配这个值效果是一样的。

图片 14

匹配字段值对(divisor)取模,值等于(remainder)的文档。

_id:3,

>    start =newDate("1990/01/01")>    db.users.find({"birthday": {"$lt": start}})

结果是不行的!!我们可以使用$where运算符来进行相应的操作。

//等同于{ $and: [ { name: "t1" }, { amount: { $lt:50 } } ] }db.inventory.find({ name: "t1" , amount: { $lt:50 }} )

比较文档中的两个键的值是否相等.例如查找出banana等于peach键值的文档(4种方法):

本文由杏彩发布,转载请注明来源

关键词: