mongoose 存储数组里为什么我这么是空数组

MongoDB各种查询操作详解
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了MongoDB各种查询操作详解,包括比较查询、关联查询、数组查询等,需要的朋友可以参考下
一、find操作
MongoDB中使用find来进行查询,通过指定find的第一个参数可以实现全部和部分查询。
1、查询全部
空的查询文档{}会匹配集合的全部内容。如果不指定查询文档,默认就是{}。
2、部分查询
3、键的筛选
键的筛选是查询时只返回自己感兴趣的键值,通过指定find的第二个参数来实现。这样可以节省传输的数据量,又能节省客户端解码文档的时间和内存消耗。
查询时,数据库所关心的查询文档的值必须是常量。
二、查询条件
1、比较查询
$lt,$lte,$gt,$gte,$ne和&,&=,&,&=,!=是一一对应的,它们可以组合起来以查找一个范围内的值。
2、关联查询
$in用于查询一个键的多个值,$nin将返回与筛选数组中所有条件都不匹配的文档。将$in与$not组合可以实现$nin相同的效果。
$or用于对多个键做or查询。
三、特定类型的查询
1、null查询
null不仅能匹配自身,还能匹配键不存在的文档。
2、正则表达式
3、数组查询
$all:通过多个元素来匹配数组。
$size:查询指定长度的数组。
$slice:返回数组的一个子集合。
4、内嵌文档查询
四、$where查询
$where查询是MongoDB的高级查询部分,可以执行任意JavaScript作为查询的一部分,是其他查询方式的一个补充。
$where查询需要将每个文档从BSON转换为JavaScript对象,然后通过$where的表达式来运行,该过程不能利用索引,所以查询速度较常规查询慢很多。如果必须使用时,可以将常规查询作为前置过滤,能够利用索引的话可以使用索引根据非$where子句进行过滤,最后使用$where对结果进行调优。另一种方式采用映射化简-MapReduce.
游标是很有用的东西,MongoDB数据库使用游标来返回find的执行结果。客户端使用游标可以对最终结果进行有效的控制,比如分页,排序。
1、limit,skip和sort
limit:限制结果数量,限制的是上限。skip:略过匹配到的前n个文档,然后返回余下的文档。skip略过过多的文档时会产生性能问题,建议尽量避免。sort:按照指定的键对文档进行排序,1为升序,-1为降序。
2、高级查询选项
包装查询:使用sort,limit或skip对最终结果进行进一步的控制。
有用的配置选项:
$maxscan:integer,指定查询最多扫描的文档数量。$min:document,查询的开始条件。$max:document,查询的结束条件。$hint:document,指定服务器使用哪个索引进行查询。$explain:boolean,获取查询执行的细节(用到的索引,结果数量,耗时等),而并非真正执行查询。$snapshot:boolean,确保查询的结果是在查询执行那一刻的一致快照,用于避免不一致读取。
包装查询会将查询条件包装到一个更大的查询文档中,比如执行如下查询时:
db.foo.find({"name":"bar"}).sort("x":1)shell会把查询从{"name":"bar"}转换成{"$query":{"name":"bar"},"$orderby":{"x":1}},而不是直接将{"name":"bar"}作为查询文档发送给数据库。
3、游标内幕看待游标的两种角度:客户端的游标及客户端游标表示的数据库游标(服务器端)。
在服务器端,游标消耗内存和其他资源,所以在合理的情况下需要尽快释放。服务器端导致游标终止的情况如下:
1、游标完成匹配结果的迭代时自动清除。
2、游标在客户端已不在作用域内的情况下,驱动会向服务器发送专门的消息,让其销毁游标。
3、超时销毁,可以使用immortal函数关闭游标超时时间,采用此操作一定要在迭代完结果后将游标关闭。
使用MongoDB需要对文档结构进行合理的设计,以满足某些特定需求。比如随机选取文档,使用skip跳过随机个文档就没有在文档中加个随机键,然后使用某个随机数对文档进行查询高效,随机键还能添加索引,效率更高。合理选择,合理设计。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具MongoDB 查询上 - refactor - 博客园
MongoDB使用find来进行查询.查询就是返回一个集合中文档的子集,子集合的范围从0个文档到整个集合.find的第一个参数
决定了要返回哪些文档.其形式也是一个文档,说明要查询的细节.
空的查询文档{}会匹配集合的全部内容.要是不指定查询文档,默认是{}.
如:db.users.find()返回集合users中的所有内容.
向查询文档中添加键值对,就意味着添加了查询条件.对绝大多数类型来说,整数匹配整数,布尔类型匹配布尔类型,字符串匹配
2.指定返回的键
有时并不需要返回文档中的所有键值对返回.可以通过find或findOne的第二个参数来指定要返回的键.这样做能节省传输的
数据量,又能节省客户端解码文档的时间和内存消耗.
db.users.findOne({"name":"refactor"},{"age":1,"sex":1})
只会将键为_id,age,sex的数据返回.
"_id"键总是会被返回.
也可以用第二个参数来剔除查询结果中的某个键值对.
键name不会显示在返回的结果中
db.users.findOne({"name":"refactor"},{"name":0})
只会将键为age,sex的数据返回."_id"键是不会返回的
db.users.findOne({"name":"refactor"},{"age":1,"sex":1,"_id":0})
3.查询条件
"$lt","$lte","$gt","$gte"分别对应&,&=,&,&=
查询age &=18 &&=30
db.users.find({"age":{"$gte":18,"$lte":30}})
向文档增加键birthday
db.users.update(  {"name":"refactor"},  {    "$set":    {      "birthday":new Date("")    }  })
查询birthday日期是之前的人
db.users.find({"birthday":{"$lt":new Date("")}})
查出所有name不等refactor1的文档,注意 文档中不存在键name的文档也会被查出来
db.users.find({"name":{"$ne":"refactor1"}})
使用or查询
MongoDB可以使用"$in","$or"
查询出pageViews为的数据
db.users.find({pageViews:{"$in":[]}})
"$in"可以指定不同类型的条件和值,如正在将用户的ID号迁移成用户名的过程中,要做到两者兼顾的查询:
db.users.find({"user_id":{"$in":[12345,"refactor"]}})
这会匹配user_id为12345和"refactor"的文档.
要是&"$in"的数组只有一个值和直接匹配这个值效果是一样的.
db.users.find({"pageViews":{"$in":[10000]}})db.users.find({"pageViews":10000})
使用"$nin"返回与数组中所有条件都不匹配的文档
如&查出所有pageViews不等的文档,注意 文档中不存在键pageViews的文档也会被查出来
db.users.find({"pageViews":{"$nin":[]}})
"$in"能对单个键进行or查询.
db.users.find(  {    "$or":    [      {"pageViews":{"$in":[]}},      {"url":"/refactor"}    ]  })
这将查询出pageViews是或url是的文档.
注意:使用普通的and查询时,要尽量将最苛刻的条件放在前面.
使用"$not"
"$not"可以用在任何条件之上.
db.users.find(  {"id_num":{"mod":[5,1]}})
这会查询出id_num取模后值为1的文档.
db.users.find(  {"id_num":{"$not":{"mod":[1,5]}}})
4.条件句的规则
在查询中,"$lt"在内层文档,在更新中"$inc" 是外层文档的键.
条件句是内层文档的键,修改器是外层文档的键.
可对一个键应用多个条件,但一个键不能对应多个更新修改器.
5.特定于类型的查询
null可以匹配自身,而且可以匹配"不存在的"
能查出url 是"/refactor",pageViews为null的文档
db.users.find({"url":"/refactor","pageViews":null})
能查出pageViews为null的文档,不存在键pageViews的也能查出来
db.users.find({"pageViews":null})
能查出url 是"/refactor",pageViews为null的文档,但不能查出不存在键pageViews的的文档db.users.find({"url":"/refactor","pageViews":{"$in":[null],"$exists":true}})
MongoDB没有"$eq"操作符,但是只有一个元素的"$in"的操作效果是一样的
如果仅仅想要匹配键值为null的文档,既要检查该键的值是否为null,还要通过"$exists"条件判断该键是不是存在.
6.正则表达式
正则表达式能够灵活有效的匹配字符串.
查找所有名包含refact或Refact的用户,使用正则表达式执行忽略大小写的匹配
db.users.find({"name":/refact/i})
系统可以接受正则表达式标识(i),但不是一定有.现在匹配了各种大小写形式的refact.
MongoDB可以为前缀型正则表达式(如:/^refactor/)查询创建索引.所以这种类型的查询非常高效.
正则表达式也可以匹配自身
db.users.find({"name":/refact/})
可以查出name为/refact/的文档.
7.查询数组
数组很大多数情况下可以这样理解:每一个元素都是整个键的值.
db.users.findOne({"userName":"refactor","emails":""})能匹配到
使用"$all"
如果需要多个元素来匹配数组,就要用"$all"
db.users.insert({"userName":"refactor",emails:["","",""]})db.users.insert({"userName":"refactor",emails:["","",""]})db.users.insert({"userName":"refactor",emails:["","",""]})
要找到邮箱有""又有"",顺序无关紧要的文档db.users.find(   {
    "emails":
      "$all":
      [
        "",
        ""
      ]
    }   })
要是只对一个元素的数组使用"$all"就和不用"$all"是一样的,如
db.users.find({"emails":{"$all":[""]}})db.users.find({"emails":""})
效果是一样的.
也可以精确的匹配数组
db.users.find({"userName":"refactor",emails:["","",""]})
若想查询数组指定位置的元素,需要使用key.index语法指定下标
db.users.find({"emails.1":""})
使用"$size"
"$size"可以查询指定长度的数组
查询数组长度为3的数组
db.users.find({"emails":{"$size":3}})
常见的查询是数组长度范围的查询."$size"并不能与其他查询子句组合(如:"$gt"),但是这种查询可以通过
在文档中添加一个"size"键的方式来实现.这样每一次向指定数组添加元素的时候,同时增加"size"值.原来这样
db.users.update({"$push":{"emails":""}})
变成这样的更新:db.users.update({"$push":{"emails":""},"$inc":{"size":1}})
这样就可以这样查询了
db.users.find({"size":{"$gt":3}})
使用"$slice"查询
find的第二个参数是可选的,可以指定返回那些键,"$slice"返回数组的一个子集合
返回emails数组的前两个元素
db.users.find({"userName":"refactor"},{"emails":{"$slice":2}})
返回emails数组的后两个元素
db.users.find({"userName":"refactor"},{"emails":{"$slice":-2}})
返回emails数组的第2个和第11个元素.如果数组不够11个,则返回第2个后面的所有元素
db.users.find({"userName":"refactor"},{"emails":{"$slice":[1,10]}})
"$slice"默认将返回文档中的所有键.&
评论 - 12927011人阅读
web研发(29)
Model.find
Mongoose 模型提供了 find, findOne, 和 findById 方法用于文档查询。
Model.find
Model.find(query, fields, options, callback)
// fields 和 options 都是可选参数
Model.find({ '': 5 }, function (err, docs) { // docs 是查询的结果数组 });
只查询指定键的结果
Model.find({}, ['first', 'last'], function (err, docs) {
// docs 此时只包含文档的部分键值
Model.findOne
与 Model.find 相同,但只返回单个文档
Model.findOne({ age: 5}, function (err, doc){
// doc 是单个文档
Model.findById
与 findOne 相同,但它接收文档的 _id 作为参数,返回单个文档。_id 可以是字符串或 ObjectId 对象。
Model.findById(obj._id, function (err, doc){
// doc 是单个文档
Model.count
返回符合条件的文档数。
Model.count(conditions, callback);
Model.remove
删除符合条件的文档。
Model.remove(conditions, callback);
Model.distinct
查询符合条件的文档并返回根据键分组的结果。
Model.distinct(field, conditions, callback);
Model.where
当查询比较复杂时,用 where:
.where('age').gte(25)
.where('tags').in(['movie', 'music', 'art'])
.select('name', 'age', 'tags')
.limit(10)
.asc('age')
.slaveOk()
.hint({ age: 1, name: 1 })
.run(callback);
Model.$where
有时我们需要在 mongodb 中使用 javascript 表达式进行查询,这时可以用 find({$where : javascript}) 方式,$where 是一种快捷方式,并支持链式调用查询。
Model.$where('this.firstname === this.lastname').exec(callback)
Model.update
使用 update 子句更新符合指定条件的文档,更新数据在发送到数据库服务器之前会改变模型的类型。
var conditions = { name: 'borne' }
, update = { $inc: { visits: 1 }}
, options = { multi: true };
Model.update(conditions, update, options, callback)
注意:为了向后兼容,所有顶级更新键如果不是原子操作命名的,会统一被按 $set 操作处理,例如:
var query = { name: 'borne' };
Model.update(query, { name: 'jason borne' }, options, callback)
// 会被这样发送到数据库服务器
Model.update(query, { $set: { name: 'jason borne' }}, options, callback)
如果不提供回调函数,所有这些方法都返回 Query 对象,它们都可以被再次修改(比如增加选项、键等),直到调用 exec 方法。
var query = Model.find({});
query.where('field', 5);
query.limit(5);
query.skip(100);
query.exec(function (err, docs) {
// called when the `plete` or `query.error` are called
// internally
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:282733次
积分:2426
积分:2426
排名:第12023名
原创:46篇
转载:24篇
评论:34条
(5)(3)(3)(2)(1)(4)(3)(15)(2)(1)(2)(2)(1)(5)(3)(1)(2)(5)(3)(2)(1)(3)(1)}

我要回帖

更多关于 mongoose 数组 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信