http://www.runoob.com/mongodb/mongodb-query.html
db.col.insert({
title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by: '菜鸟教程',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
db.stats()
db #当前所在库
show dbs
use test
show collections
db.col.insert({title:'MongoDB 教程',description:'MongoDB 是一个Nosql数据库',by:'菜鸟教程',url:'http://www.runoob.com',tags:['mongodb','database','NoSQL'],likes: 100 })
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true}) #title 更换成MongoDB
db.col.update({"_id" : ObjectId("56936748e454fe4553a95c45")},{"$set":{"likes":"200"}}) #更新集合中字段likes:200
db.col.update({"_id" : ObjectId("569368c9e454fe4553a95c47")},{"$set":{"tags":"[mongodb,NoSQL,mysql]"}})
db.col.remove({"_id" : ObjectId("56944cdc39c6f2c9e09629d3")})
db.col.find()
db.col.find().pretty() #以易读的方式来读取数据
db.col.find().limit(2); #读取2条
db.col.find().limit(2).skip(2); #读取第3,4条,跳过起始的2条
db.col.find().sort({KEY:1}) #升序排列
db.col.find().sort({KEY:-1}) #降序排列
db.col.remove({}) 清空col集合
#删除test_db
use test_db
db.dropDatabase()
#向col集合添加字段add项 mongos> db.col.update({},{$set:{"add":"ok"}},true,true) WriteResult({ "nMatched" : 5, "nUpserted" : 0, "nModified" : 5 }) #删除col集合字段add项 mongos> db.col.update({"likes":{$gt:10}},{$unset:{"add":""}},true) WriteResult({ "nMatched" : 5, "nUpserted" : 0, "nModified" : 5 }) #修改字段名 mongos> db.col.update({},{$rename:{"title":"titlee"}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) mongos> db.col.update({},{$rename:{"title":"titlee"}},true,true) WriteResult({ "nMatched" : 5, "nUpserted" : 0, "nModified" : 4 })
使用过mysql的人知道in是完全匹配的,如果想实现匹配其中的一个字段,那么需要使用find_in_set. 在使用mongodb开发的过程中遇到过类似的需求,实现方法也很简单,只需使用in即可,如果是all的话,那么表示完全匹配。来看个实例
mongodb $in 查询
123 > db . col_content . find ( { 'nodeID' : { $ in : [ '7788' ] } } ){ "_id" : ObjectId ( "525baa67539d1ec00700002a" ) , "nodeID" : [ "7788" ] , "i" : 3 }{ "_id" : ObjectId ( "525baab1539d1ec00700002b" ) , "nodeID" : [ "123" , "7788" ] , "i" : 4 }mongodb $all 查询
#常用操作符http://www.cnblogs.com/andylaufzf/archive/2011/11/10/2244732.html
MongoDB 与 RDBMS Where 语句比较
如果你熟悉常规的 SQL 数据,通过下表可以更好的理解 MongoDB 的条件语句查询:equal 等于,not equal 不等于,less少的,great 大的
操作 | 格式 | 范例 | RDBMS中的类似语句 |
---|---|---|---|
等于 | {<key>:<value> } | db.col.find({"by":"菜鸟教程"}).pretty() | where by = '菜鸟教程' |
小于 | {<key>:{$lt:<value>}} | db.col.find({"likes":{$lt:50}}).pretty() | where likes < 50 |
小于或等于 | {<key>:{$lte:<value>}} | db.col.find({"likes":{$lte:50}}).pretty() | where likes <= 50 |
大于 | {<key>:{$gt:<value>}} | db.col.find({"likes":{$gt:50}}).pretty() | where likes > 50 |
大于或等于 | {<key>:{$gte:<value>}} | db.col.find({"likes":{$gte:50}}).pretty() | where likes >= 50 |
不等于 | {<key>:{$ne:<value>}} | db.col.find({"likes":{$ne:50}}).pretty() | where likes != 50 |
<pre class="prettyprint prettyprinted" style="border-width: 1px 1px 1px 4px; border-style: solid; border-color: rgb(221, 221, 221); margin: 15px auto; padding: 10px 15px; font-stretch: normal; line-height: 20px; font-family: 'courier new'; word-break: break-all; word-wrap: break-word; color: rgb(51, 51, 51); background: url(http://www.runoob.com/images/codecolorer_bg.gif) 50% 0% rgb(251, 251, 251);"><span class="typ" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">Select</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">*</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="kwd" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">from</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> col </span><span class="kwd" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">where</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> likes </span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">></span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="lit" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 102, 102);">22</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">;</span>
MongoDB 使用 (<) 和 (>) 查询 - $lt 和 $gt
如果你想获取"col"集合中 "likes" 大于100,小于 200 的数据,你可以使用以下命令:
db.col.find({likes : {$lt :200, $gt : 100}})
类似于SQL语句:
Select * from col where likes>100 AND likes<200;
输出结果:
> db.col.find({likes : {$lt :200, $gt : 100}}) { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } >
mongos> db.col.find({"name":"pp","age":{$gt:20}})
{ "_id" : ObjectId("569455de39c6f2c9e09629d5"), "name" : "pp", "age" : 21 }
{ "_id" : ObjectId("569455e839c6f2c9e09629d7"), "name" : "pp", "age" : 22 }
{ "_id" : ObjectId("569455eb39c6f2c9e09629d8"), "name" : "pp", "age" : 23 }
mongos> db.col.find({"name":"pp","age":{$lt:20}})
{ "_id" : ObjectId("569455e239c6f2c9e09629d6"), "name" : "pp", "age" : 19 }
MongoDB AND 条件
MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,及常规 SQL 的 AND 条件。
语法格式如下:
以下实例通过 by 和 title 键来查询 菜鸟教程 中 MongoDB 教程 的数据
类似于 WHERE 语句:WHERE by='菜鸟教程' AND title='MongoDB 教程'
>db.col.find({key1:value1, key2:value2}).pretty()
mongos> db.col.find({"name":"pp","age":20})
{ "_id" : ObjectId("569455d839c6f2c9e09629d4"), "name" : "pp", "age" : 20 }
MongoDB OR 条件
MongoDB OR 条件语句使用了关键字 $or,语法格式如下:
实例
以下实例中,我们演示了查询键 by 值为 菜鸟教程 或键 title 值为 MongoDB 教程 的文档。
>db.col.find( { $or: [ {key1: value1}, {key2:value2} ] } ).pretty()
mongos> db.col.find({$or:[{"name":"pp"},{"age":20}]})
{ "_id" : ObjectId("569455d839c6f2c9e09629d4"), "name" : "pp", "age" : 20 }
{ "_id" : ObjectId("569455de39c6f2c9e09629d5"), "name" : "pp", "age" : 21 }
{ "_id" : ObjectId("569455e239c6f2c9e09629d6"), "name" : "pp", "age" : 19 }
AND 和 OR 联合使用
以下实例演示了 AND 和 OR 联合使用,类似常规 SQL 语句为: 'where url='http://www.runoob.com' AND (by = '菜鸟教程' OR title = 'MongoDB 教程')'
>db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty() { "_id" : ObjectId("56063f17ade2f21f36b03133"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
mongos> db.col.find({"age":{$lt:30},$or:[{"name":"pp"},{"age":20}]})
{ "_id" : ObjectId("569455d839c6f2c9e09629d4"), "name" : "pp", "age" : 20 }
{ "_id" : ObjectId("569455de39c6f2c9e09629d5"), "name" : "pp", "age" : 21 }
{ "_id" : ObjectId("569455e239c6f2c9e09629d6"), "name" : "pp", "age" : 19 }
{ "_id" : ObjectId("569455e839c6f2c9e09629d7"), "name" : "pp", "age" : 22 }
{ "_id" : ObjectId("569455eb39c6f2c9e09629d8"), "name" : "pp", "age" : 23 }
{ "_id" : ObjectId("569455ed39c6f2c9e09629d9"), "name" : "pp", "age" : 24 }
{ "_id" : ObjectId("569455f039c6f2c9e09629da"), "name" : "pp", "age" : 25 }
MongoDB $type 操作符
描述
在本章节中,我们将继续讨论MongoDB中条件操作符 $type。
$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。
MongoDB 中可以使用的类型如下表所示:
类型 | 数字 | 备注 |
---|---|---|
Double | 1 | |
String | 2 | |
Object | 3 | |
Array | 4 | |
Binary data | 5 | |
Undefined | 6 | 已废弃。 |
Object id | 7 | |
Boolean | 8 | |
Date | 9 | |
Null | 10 | |
Regular Expression | 11 | |
JavaScript | 13 | |
Symbol | 14 | |
JavaScript (with scope) | 15 | |
32-bit integer | 16 | |
Timestamp | 17 | |
64-bit integer | 18 | |
Min key | 255 | Query with -1. |
Max key | 127 |
MongoDB 使用 ensureIndex() 方法来创建索引。
MongoDB的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的优化技巧。下面是创建索引的命令:
> db.test.ensureIndex({"username":1})
可以通过下面的名称查看索引是否已经成功建立:
> db.test.getIndexes()
删除索引的命令是:
> db.test.dropIndex({"username":1})
在MongoDB中,我们同样可以创建复合索引,如:
-- 数字1表示username键的索引按升序存储,-1表示age键的索引按照降序方式存储。
> db.test.ensureIndex({"username":1, "age":-1})
该索引被创建后,基于username和age的查询将会用到该索引,或者是基于username的查询也会用到该索引,但是只是基于age的查询将不会用到该复合索引。因此可以说,如果想用到复合索引,必须在查询条件中包含复合索引中的前N个索引列。然而如果查询条件中的键值顺序和复合索引中的创建顺序不一致的话,MongoDB可以智能的帮助我们调整该顺序,以便使复合索引可以为查询所用。如:
> db.test.find({"age": 30, "username": "stephen"})
对于上面示例中的查询条件,MongoDB在检索之前将会动态的调整查询条件文档的顺序,以使该查询可以用到刚刚创建的复合索引
<span style="white-space:pre"></span><pre name="code" class="python" style="color: rgb(51, 51, 51); line-height: 24px;"><span style="font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"> > db.system.indexes.find()</span>
<span style="font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"><span style="white-space:pre"> </span> system.indexes集合中包含了每个索引的详细信息,因此可以通过下面的命令查询已经存在的索引,如:</span><br style="font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;" /><span style="font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"></span><pre name="code" class="python" style="color: rgb(51, 51, 51); line-height: 24px;"><span style="font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"> > db.test.ensureIndex({"username":1},{"background":true})</span>
<span style="font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"> 如果在为已有数据的文档创建索引时,可以执行下面的命令,以使MongoDB在后台创建索引,这样的创建时就不会阻塞其他操作。但是相比而言,以阻塞方式创建索引,会使整个创建过程效率更高,但是在创建时MongoDB将无法接收其他的操作。</span><br style="font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;" /><span style="font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif; line-height: 18px;"> </span>
MongoDB 聚合 aggregate()
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。
语法
aggregate() 方法的基本语法格式如下所示:
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
{
"_id" : ObjectId("569467f639c6f2c9e09629e1"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "菜鸟教程",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 1111
}
{
"_id" : ObjectId("5694680139c6f2c9e09629e2"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "菜鸟教程",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 101
}
{
"_id" : ObjectId("56947821037ae33010a30e82"),
"title" : "MongoDB Overview",
"description" : "MongoDB is no sql database",
"by_user" : "w3cschool.cc",
"url" : "http://www.w3cschool.cc",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
mongos> db.col.aggregate([{$group:{_id:"$title",num_tutorial:{$sum:1}}}])
{ "_id" : "MongoDB 教程", "num_tutorial" : 6 }
{ "_id" : "Java 教程", "num_tutorial" : 1 }
{ "_id" : "MongoDB Overview", "num_tutorial" : 4 }
以上实例类似sql语句:
select title, count(*) from col group by title
在上面的例子中,我们通过字段by_user字段对数据进行分组,并计算by_user字段相同值的总和。
下表展示了一些聚合的表达式:
表达式 | 描述 | 实例 |
---|---|---|
$sum | 计算总和。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) |
$avg | 计算平均值 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) |
$min | 获取集合中所有文档对应值得最小值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) |
$max | 获取集合中所有文档对应值得最大值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) |
$push | 在结果文档中插入值到一个数组中。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) |
$addToSet | 在结果文档中插入值到一个数组中,但不创建副本。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
$first | 根据资源文档的排序获取第一个文档数据。 | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
$last | 根据资源文档的排序获取最后一个文档数据 | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
MongoDB 分片
分片
在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求。
当MongoDB存储海量的数据时,一台机器可能不足以存储数据也足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。
http://www.lanceyan.com/tech/arch/mongodb_shard1.html
http://my.oschina.net/costaxu/blog/196980#OSC_h1_7MongoDB 覆盖索引查询
官方的MongoDB的文档中说明,覆盖查询是以下的查询:
- 所有的查询字段是索引的一部分
- 所有的查询返回字段在同一个索引中
由于所有出现在查询中的字段是索引的一部分, MongoDB 无需在整个数据文档中检索匹配查询条件和返回使用相同索引的查询结果。
因为索引存在于RAM中,从索引中获取数据比通过扫描文档读取数据要快得多。
使用覆盖索引查询
为了测试盖索引查询,使用以下 users 集合:
{ "_id": ObjectId("53402597d852426020000002"), "contact": "987654321", "dob": "01-01-1991", "gender": "M", "name": "Tom Benzamin", "user_name": "tombenzamin" }
我们在 users 集合中创建联合索引,字段为 gender 和 user_name :
>db.users.ensureIndex({gender:1,user_name:1})
现在,该索引会覆盖以下查询:
>db.users.find({gender:"M"},{user_name:1,_id:0})
也就是说,对于上述查询,MongoDB的不会去数据库文件中查找。相反,它会从索引中提取数据,这是非常快速的数据查询。
由于我们的索引中不包括 _id 字段,_id在查询中会默认返回,我们可以在MongoDB的查询结果集中排除它。
下面的实例没有排除_id,查询就不会被覆盖:
>db.users.find({gender:"M"},{user_name:1})
MongoDB 原子操作
mongodb不支持事务,所以,在你的项目中应用时,要注意这点。无论什么设计,都不要要求mongodb保证数据的完整性。
但是mongodb提供了许多原子操作,比如文档的保存,修改,删除等,都是原子操作。
所谓原子操作就是要么这个文档保存到Mongodb,要么没有保存到Mongodb,不会出现查询到的文档没有保存完整的情况。
原子操作常用命令
$set
用来指定一个键并更新键值,若键不存在并创建。
{ $set : { field : value } } #db.col.update({},{$set:{age:[1,2,3]}},true,true)
$unset
用来删除一个键。
{ $unset : { field : 1} } #db.col.update({},{$unset:{age:""}},true,true)
$inc
$inc可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作。
{ $inc : { field : value } } #db.col.update({"likes":""},{$inc:{"likes":100}},true,true)
$push
用法:
{ $push : { field : value } } #db.col.update({},{$push:{"tags":"mssql"}},1,1)
把value追加到field里面去,field一定要是数组类型才行,如果field不存在,会新增一个数组类型加进去。
$pushAll
同$push,只是一次可以追加多个值到一个数组字段内。
{ $pushAll : { field : value_array } } #db.col.update({},{$pushAll:{"tags":[1,2,3]}})
$pull
从数组field内删除一个等于value值。
{ $pull : { field : _value } } #db.col.update({},{$pull:{tags:"mongodb"}},1,1)
$addToSet
增加一个值到数组内,而且只有当这个值不在数组内才增加。
$pop
删除数组的第一个或最后一个元素
{ $pop : { field : 1 } } #db.col.update({},{$pop:{"tags":1}})
$rename
修改字段名称
{ $rename : { old_field_name : new_field_name } } #db.col.update({},{$rename:{'tags':'arr'}},1,1)
$bit
位操作,integer类型
{$bit : { field : {and : 5}}}
偏移操作符
> t.find() { "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC", "comments" : [ { "by" : "joe", "votes" : 3 }, { "by" : "jane", "votes" : 7 } ] } > t.update( {'comments.by':'joe'}, {$inc:{'comments.$.votes':1}}, false, true ) > t.find() { "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC", "comments" : [ { "by" : "joe", "votes" : 4 }, { "by" : "jane", "votes" : 7 } ] }
MongoDB 高级索引
考虑以下文档集合(users ):
{ "address": { "city": "Los Angeles", "state": "California", "pincode": "123" }, "tags": [ "music", "cricket", "blogs" ], "name": "Tom Benzamin" }
以上文档包含了 address 子文档和 tags 数组。
索引数组字段
假设我们基于标签来检索用户,为此我们需要对集合中的数组 tags 建立索引。
在数组中创建索引,需要对数组中的每个字段依次建立索引。所以在我们为数组 tags 创建索引时,会为 music、cricket、blogs三个值建立单独的索引。
使用以下命令创建数组索引:
>db.users.ensureIndex({"tags":1})
创建索引后,我们可以这样检索集合的 tags 字段:
>db.users.find({tags:"cricket"})
为了验证我们使用使用了索引,可以使用 explain 命令:
>db.users.find({tags:"cricket"}).explain()
以上命令执行结果中会显示 "cursor" : "BtreeCursor tags_1" ,则表示已经使用了索引。
索引子文档字段
假设我们需要通过city、state、pincode字段来检索文档,由于这些字段是子文档的字段,所以我们需要对子文档建立索引。
为子文档的三个字段创建索引,命令如下:
>db.users.ensureIndex({"address.city":1,"address.state":1,"address.pincode":1})
一旦创建索引,我们可以使用子文档的字段来检索数据:
>db.users.find({"address.city":"Los Angeles"})
记住查询表达式必须遵循指定的索引的顺序。所以上面创建的索引将支持以下查询:
>db.users.find({"address.city":"Los Angeles","address.state":"California"})
同样支持以下查询:
>db.users.find({"address.city":"LosAngeles","address.state":"California","address.pincode":"123"})
启用全文检索
MongoDB 在 2.6 版本以后是默认开启全文检索的,如果你使用之前的版本,你需要使用以下代码来启用全文检索:
>db.adminCommand({setParameter:true,textSearchEnabled:true})
或者使用命令:
mongod --setParameter textSearchEnabled=true
创建全文索引
考虑以下 posts 集合的文档数据,包含了文章内容(post_text)及标签(tags):
{ "post_text": "enjoy the mongodb articles on w3cschool.cc", "tags": [ "mongodb", "w3cschool" ] }
我们可以对 post_text 字段建立全文索引,这样我们可以搜索文章内的内容:
>db.posts.ensureIndex({post_text:"text"})
使用全文索引
现在我们已经对 post_text 建立了全文索引,我们可以搜索文章中的关键词w3cschool.cc:
>db.posts.find({$text:{$search:"w3cschool.cc"}})
以下命令返回了如下包含w3cschool.cc关键词的文档数据:
{ "_id" : ObjectId("53493d14d852429c10000002"), "post_text" : "enjoy the mongodb articles on w3cschool.cc", "tags" : [ "mongodb", "w3cschool" ] } { "_id" : ObjectId("53493d1fd852429c10000003"), "post_text" : "writing tutorials on w3cschool.cc", "tags" : [ "mongodb", "tutorial" ] }
如果你使用的是旧版本的MongoDB,你可以使用以下命令:
>db.posts.runCommand("text",{search:" w3cschool.cc"})
使用全文索引可以提高搜索效率。
删除全文索引
删除已存在的全文索引,可以使用 find 命令查找索引名:
>db.posts.getIndexes()
通过以上命令获取索引名,本例的索引名为post_text_text,执行以下命令来删除索引:
>db.posts.dropIndex("post_text_text")
MongoDB 正则表达式
正则表达式是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。
许多程序设计语言都支持利用正则表达式进行字符串操作。
MongoDB 使用 $regex 操作符来设置匹配字符串的正则表达式。
MongoDB使用PCRE (Perl Compatible Regular Expression) 作为正则表达式语言。
不同于全文检索,我们使用正则表达式不需要做任何配置。
考虑以下 posts 集合的文档结构,该文档包含了文章内容和标签:
{ "post_text": "enjoy the mongodb articles on tutorialspoint", "tags": [ "mongodb", "tutorialspoint" ] }
使用正则表达式
以下命令使用正则表达式查找包含 w3cschool.cc 字符串的文章:
>db.posts.find({post_text:{$regex:"w3cschool.cc"}})
以上查询也可以写为:
>db.posts.find({post_text:/w3cschool.cc/})
不区分大小写的正则表达式
如果检索需要不区分大小写,我们可以设置 $options 为 $i。
以下命令将查找不区分大小写的字符串 w3cschool.cc:
>db.posts.find({post_text:{$regex:"w3cschool.cc",$options:"$i"}})
集合中会返回所有包含字符串 w3cschool.cc 的数据,且不区分大小写:
{ "_id" : ObjectId("53493d37d852429c10000004"), "post_text" : "hey! this is my post on W3Cschool.cc", "tags" : [ "tutorialspoint" ] }
数组元素使用正则表达式
我们还可以在数组字段中使用正则表达式来查找内容。 这在标签的实现上非常有用,如果你需要查找包含以 tutorial 开头的标签数据(tutorial 或 tutorials 或 tutorialpoint 或 tutorialphp), 你可以使用以下代码:
>db.posts.find({tags:{$regex:"tutorial"}})
优化正则表达式查询
- 如果你的文档中字段设置了索引,那么使用索引相比于正则表达式匹配查找所有的数据查询速度更快。
- 如果正则表达式是前缀表达式,所有匹配的数据将以指定的前缀字符串为开始。例如: 如果正则表达式为 ^tut ,查询语句将查找以 tut 为开头的字符串。
这里面使用正则表达式有两点需要注意:
正则表达式中使用变量。一定要使用eval将组合的字符串进行转换,不能直接将字符串拼接后传入给表达式。否则没有报错信息,只是结果为空!实例如下:
var name=eval("/" + 变量值key +"/i");
以下是模糊查询包含title关键词, 且不区分大小写:
title:eval("/"+title+"/i") // 等同于 title:{$regex:title,$Option:"$i"}