接着上午中的CRUD操作,在Reading中,mongoDB提供了许多比较符号(Comparison Operators)供我们使用。
Comparison Operators
$eq
Syntax:{ <field>: { $eq: <value> } }
//相当于
{ field: <value> }
$eq Matches values that are equal to a specified value.
> db.movieDetails.findOne({runtime:{$eq:90}})
{
"_id" : ObjectId("569190d124de1e0ce2dfcd84"),
"title" : "Best in Show",
"year" : 2000,
"rated" : "PG-13",
"released" : ISODate("2000-10-20T04:00:00Z"),
"runtime" : 90,
"countries" : [
"USA"
],
.......................
"type" : "movie"
}
>
$gt\$gte\$lt\$lte
范围查询
Syntax: {field: {$gt: value} }
$gt Matches values that are greater than a specified value.
$gte Matches values that are greater than or equal to a specified value.
$lt Matches values that are less than a specified value.
$lte Matches values that are less than or equal to a specified value.
> db.movieDetails.find({runtime:{$gt:90,$lt:120}},{runtime:1,title:1,_id:0})
{ "title" : "A Million Ways to Die in the West", "runtime" : 116 }
{ "title" : "Wild Wild West", "runtime" : 106 }
{ "title" : "Red Rock West", "runtime" : 98 }
{ "title" : "Journey to the West", "runtime" : 110 }
{ "title" : "Adventures in Babysitting", "runtime" : 102 }
> db.movieDetails.find({runtime:{$gte:90,$lte:91},"tomato.meter":{$eq:100}},{run
time:1,title:1,_id:0,"tomato.meter":1})
{ "title" : "Mr. Death: The Rise and Fall of Fred A. Leuchter, Jr.", "runtime" :
91, "tomato" : { "meter" : 100 } }
>
$ne\$in\$nin
$ne Matches all values that are not equal to a specified value.
$in Matches any of the values specified in an array.
$nin Matches none of the values specified in an array.
> db.movieDetails.find({rated:{$nin:["G","PG"]}}).count()
2156
> db.movieDetails.find({rated:{$in:["G","PG"]}}).count()
139
> db.movieDetails.find({rated:{$ne:"PG"}}).count()
2187
>
Element Operators
$type\$exists
判断filed的value类型,判断filed是否存在(值为null,也代表存在)
- $type
Syntax: { field: { $type: <BSON type number> | <String alias> } }
- $exists
Syntax: { field: { $exists: <boolean> } }
> db.moviesScratch.find({_id:{$type:"objectId"}}).count()
4
> db.moviesScratch.find({_id:{$type:"string"}}).count()
4
> db.moviesScratch.find({title:{$exists:1}}).count()
8
> db.moviesScratch.find({title:{$exists:true}}).count()
8
>
Available Types
Changed in version 3.2: $type operator accepts string aliases for the
BSON types in addition to the numbers corresponding to the BSON types.
Previous versions only accepted the numbers corresponding to the BSON
type.
Type Number Alias Notes
Double 1 “double”
String 2 “string”
Object 3 “object”
Array 4 “array”
Binary data 5 “binData”
Undefined 6 “undefined” Deprecated.
ObjectId 7 “objectId”
Boolean 8 “bool”
Date 9 “date”
Null 10 “null”
Regular Expression 11 “regex”
DBPointer 12 “dbPointer”
JavaScript 13 “javascript”
Symbol 14 “symbol”
JavaScript (with scope) 15 “javascriptWithScope”
32-bit integer 16 “int”
Timestamp 17 “timestamp”
64-bit integer 18 “long”
Min key -1 “minKey”
Max key 127 “maxKey”
Logical Query Operators
$or\$and
- $or满足任何一个条件即可
syntax:
{ $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }
- $and所有任何都要满足,主要用于重复字段的多次过滤
Syntax: { $and: [ { <expression1> }, { <expression2> } , ... , { <expressionN> } ] }
> db.movieDetails.findOne({$or:[{rated:"G"},{"tomato.meter":{$gt:100}}]})
{
"_id" : ObjectId("5692a15524de1e0ce2dfcfaa"),
"title" : "The Straight Story",
"year" : 1999,
"rated" : "G",
"released" : ISODate("1999-11-03T05:00:00Z"),
"tomato" : {
"meter" : 96,
"image" : "certified",
"rating" : 8.1,
"reviews" : 89,
"fresh" : 85,
"consensus" : "Slow-paced but heart-warming.",
"userMeter" : 91,
"userRating" : 4,
"userReviews" : 30716
},
"type" : "movie"
}
>
> db.movieDetails.find({rated:"G","tomato.meter":{$gte:100}}).count()
2
> db.movieDetails.find({$and:[{rated:"G"},{"tomato.meter":{$gte:100}}]}).count()
2
>
可以看到,
and貌似有些多余,直接写就好了。为什么要设计
and呢?
官网的解释是说,可以在一个document中多次使用同一个字段。但是我不用$and也貌似可以实现???
> db.movieDetails.find({"type":{$ne:null},"type":{$exists:true}},{"_id":1}).pret
ty()
{ "_id" : ObjectId("5753e5fbf425dbf682d14924") }
>
> db.movieDetails.find({$and:[{"type":{$ne:null}},{"type":{$exists:true}}]},{"_i
d":1}).pretty()
{ "_id" : ObjectId("5753e5fbf425dbf682d14924") }
>
> db.movieDetails.find().count()
2295
> db.movieDetails.find({"type":{$eq:null},"type":{$exists:true}}).count()
2295
> db.movieDetails.find({"type":{$exists:true},"type":{$eq:null}}).pretty()
> db.movieDetails.find({"type":{$exists:true},"type":{$eq:null}}).count()
0
>
可以看到,在一个{}中,不能重复出现同一个field,否则后边会覆盖前边的。所以mongoDB对这种情况设置了$and!
Query Operator Array
array类型的field判断符
$all Matches arrays that contain all elements specified in the query.
也就是说field必须包含 value1、value2….;顺序无所谓。
syntax:{ <field>: { $all: [ <value1> , <value2> ... ] } }
> db.movieDetails.find({genres:{$all:["Comedy","Adventure"]}},{genres:1})
{
"_id" : ObjectId("5692a14824de1e0ce2dfcf1e"),
"genres" : [
"Action",
"Adventure",
"Comedy"
]
}
{
"_id" : ObjectId("5692a14824de1e0ce2dfcf1f"),
"genres" : [
"Adventure",
"Comedy",
"Family"
]
}
{
"_id" : ObjectId("5692a14824de1e0ce2dfcf22"),
"genres" : [
"Action",
"Adventure",
"Comedy"
]
}
$elemMatch Selects documents if element in the array field matches all the specified $elemMatch conditions.
syntax:{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }
只要数组元素任意一个满足,则返回。
> db.elementMatch.find({result:{$elemMatch:{$nin:[82,85,90]}}},{result:1,_id:0})
{ "result" : [ 82, 85, 88 ] }//88满足
{ "result" : [ 75, 88, 89 ] }//75满足
> db.elementMatch.find({result:{$elemMatch:{$nin:[88,85,90]}}},{result:1,_id:0})
{ "result" : [ 82, 85, 88 ] }
{ "result" : [ 75, 88, 89 ] }
> db.elementMatch.find({result:{$elemMatch:{$nin:[82,85,90]}}},{result:1,_id:0})
{ "result" : [ 82, 85, 88 ] }
{ "result" : [ 75, 88, 89 ] }
> db.elementMatch.find({result:{$elemMatch:{$nin:[82,85,88]}}},{result:1,_id:0})
{ "result" : [ 75, 88, 89 ] }
$size Selects documents if the array field is a specified size.
数组个数满足,则返回
> db.movieDetails.find({genres:{$size:5}}).pretty()
{
"_id" : ObjectId("5692a4c324de1e0ce2dfdbd1"),
"title" : "VJ Day & Homecoming",
"year" : 2011,
"rated" : null,
"released" : null,
"runtime" : 15,
"countries" : [ ],
"genres" : [
"Documentary",
"Short",
"History",
"News",
"War"
],
"director" : "'Bill' William Sollner",
"writers" : [ ],
"actors" : [ ],
"plot" : "The celebration is used to get at serious current, especially
small town, issues.",
"poster" : null,
"imdb" : {
"id" : "tt2083391",
"rating" : null,
"votes" : null
},
"awards" : {
"wins" : 0,
"nominations" : 0,
"text" : ""
},
"type" : "movie"
}
CRUD的Reading部分就到这里,接着说一下Update相关操作
Update Documents
更新操作
db.collection.updateOne() 、db.collection.updateMany() 、db.collection.update() 、 db.collection.findAndModify()
{
<operator1>: { <field1>: <value1>, ... },
<operator2>: { <field2>: <value2>, ... },
...
}
$set
{ $set: { <field1>: <value1>, ... } }
> db.movieDetails.findOne({title:"The Martian"},{"poster":1})
{ "_id" : ObjectId("569520be699edceab722522a"), "poster" : "http://" }
> db.movieDetails.updateOne({title:"The Martian"},{$set:{"poster":"poster"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.movieDetails.findOne({title:"The Martian"},{"poster":1})
{ "_id" : ObjectId("569520be699edceab722522a"), "poster" : "poster" }
> db.movieDetails.updateOne({title:"The Martian"},{$set:{"poster":{field1:1,fiel
d2:2}}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.movieDetails.findOne({title:"The Martian"},{"poster":1})
{
"_id" : ObjectId("569520be699edceab722522a"),
"poster" : {
"field1" : 1,
"field2" : 2
}
}
>
$inc
使numeric类型的字段增加一定数量 ;注意期望修改的field类型必须是numeric
{ $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } }
> db.movieDetails.findOne({"director":"Sergio Leone"},{metacritic:1})
{ "_id" : ObjectId("569190ca24de1e0ce2dfcd4f"), "metacritic" : 80 }
> db.movieDetails.updateOne({"director":"Sergio Leone"},{$inc:{metacritic:100}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.movieDetails.findOne({"director":"Sergio Leone"},{metacritic:1})
{ "_id" : ObjectId("569190ca24de1e0ce2dfcd4f"), "metacritic" : 180 }
>
$push
给数组类型字段加入元素(如果不存在这个字段,则生成一个数组类型字段)
{ $push: { <field1>: <value1>, ... } }
> db.movieDetails.updateOne({
title: "The Martian"
},
{
$push: {
reviews: {
rating: 4.5,
date: ISODate("2016-01-12T09:
00:00Z"),
reviewer: "Spencer H.",
text: "A"
}
}
})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.movieDetails.findOne({"title":"The Martian"},{"reviews":1})
{
"_id" : ObjectId("569520be699edceab722522a"),
"reviews" : [
{
"rating" : 4.5,
"date" : ISODate("2016-01-12T09:00:00Z"),
"reviewer" : "Spencer H.",
"text" : "A"
}
]
}
>
db.collection.updateMany()
> use video
switched to db video
> db.movieDetails.findOne({rated:null},{"rated":1})
{ "_id" : ObjectId("569190cf24de1e0ce2dfcd74"), "rated" : null }
> db.movieDetails.updateMany({"rated":null},{$unset:{rated:""}})
{ "acknowledged" : true, "matchedCount" : 1599, "modifiedCount" : 1599 }
> db.movieDetails.findOne({rated:null},{"rated":1})
{ "_id" : ObjectId("569190cf24de1e0ce2dfcd74") }
>
从上边的例子还可以看成, db.movieDetails.findOne({rated:null},{“rated”:1})既可以匹配“rated”字段不存在的document,也匹配rated对应值为null的字段。
更多使用请查看
upsert
var detail = {
"title" : "The Martian",
"imdb" : {
"id" : "tt3659388",
"rating" : 999,
"votes" : 999
} ,
"type":"---"
};
db.movieDetails.updateOne(
{"imdb.id": detail.imdb.id},
{$set: detail},
{upsert: true});
如果匹配存在,则更新:按照detail中的field值去替换原有movieDetails的相同field的值。否则,插入一条新的数据
replaceOne
var detail = {
"title" : "The Martian",
"imdb" : {
"id" : "tt3659388",
"rating" : 999,
"votes" : 999
} ,
"type":"---"
};
> db.movieDetails.replaceOne( {"imdb.id": detail.imdb.id}, detail);
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.movieDetails.findOne( {"imdb.id": detail.imdb.id} )
{
"_id" : ObjectId("569520be699edceab722522a"),
"title" : "The Martian",
"imdb" : {
"id" : "tt3659388",
"rating" : 999,
"votes" : 999
},
"type" : "---"
}