Mongodb及pymongo學習總結

老規矩,英文文檔:http://api.mongodb.com/python/current/examples/authentication.html

一、mongodb

1、簡介

MongoDB是一種強大、靈活、追求性能、易擴展的數據存儲方式。是面向文檔的數據庫,不是關系型數據庫,是NoSQL(not only SQL)的一種。所謂的面向文檔,就是將原來關系型數據庫中的“行”的概念換成了更加靈活的"文檔",以文檔為存儲單位。文檔的值可以是數組、文檔等復雜的數據模型。并且文檔的鍵不會事先定義也不會固定不變。mongoDB設計的主要思想之一就是,將能交給客戶端的操作都要從服務端轉移到客戶端。

文檔

文檔是MongoDB的核心、基本數據單元,類似于JS中的JSON對象,由多個key-value構成,但是支持更多的數據類型。多個鍵以及相關的值有序的放置在一起便是文檔。在大多數編程語言中都是使用多個key-value的形式,Java中是map,Python中是字典,JavaScript中是對象。

    文檔中的key/value是有序的,沒有相同的兩個文檔。
    文檔中的value的數據類型沒有限制,甚至可以是文檔。
    文檔的key一般應該是字符串。
    文檔的key不能含有空字符串,不能含有.和$以及_。
    文檔的key不能重復。
    mangoDB中,key和value都是區分數據類型和大小寫的。

集合

集合就是一組文檔,如果說文檔類似于關系數據庫中的行,那么集合就是表。集合是無模式的(模式的概念參見模式的意義)。一個集合中的文檔可以是任意類型的,也就是說文檔是可以任意組合的。

    和key一樣不能有空字符串
    不能以"system."開頭,不能含有"$"
    一個集合的完全限定名:數據庫名.集合(子集合)名稱,例如cms.blog.posts

數據庫

MangoDB中最基本的存儲單元是文檔,文檔組成集合,集合組成數據庫。一個MangoDB實例可以承載多個數據庫,數據庫之間完全獨立。一般情況下,一個應用對應一個數據庫,類似于關系數據庫中的外模式。

    不能是空字符串
    不得含有空格、點、斜杠與反斜杠以及空字符串。
    應該全部小寫
    最多64字節

2、安裝

平臺:centos 6

下載地址:https://www.mongodb.com/download-center#community

cd /usr/local

解壓:tar -zxvf mongodb-linux-x86_64-rhel62-3.2.7.tgz

移動:mv mongodb-linux-x86_64-rhel62-3.2.7 mongodb

配置環境變量,修改/etc/profile,添加如下內容:
export MONGODB_HOME=/usr/local/mongodb
export PATH=$MONGODB_HOME/bin:$Path

執行命令:
    source /etc/profile

查看mongodb版本信息 mongod -v

[root@myvpc bin]# mongod -v
2017-01-16T20:27:59.622+0800 I CONTROL  [initandlisten] MongoDB starting : pid=23389 port=27017 dbpath=/data/db 64-bit host=myvpc
2017-01-16T20:27:59.622+0800 I CONTROL  [initandlisten] db version v3.2.7
2017-01-16T20:27:59.622+0800 I CONTROL  [initandlisten] git version: 4249c1d2b5999ebbf1fdf3bc0e0e3b3ff5c0aaf2
2017-01-16T20:27:59.622+0800 I CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013
2017-01-16T20:27:59.622+0800 I CONTROL  [initandlisten] allocator: tcmalloc
2017-01-16T20:27:59.622+0800 I CONTROL  [initandlisten] modules: none
2017-01-16T20:27:59.622+0800 I CONTROL  [initandlisten] build environment:
2017-01-16T20:27:59.622+0800 I CONTROL  [initandlisten]     distmod: rhel62
2017-01-16T20:27:59.622+0800 I CONTROL  [initandlisten]     distarch: x86_64
2017-01-16T20:27:59.622+0800 I CONTROL  [initandlisten]     target_arch: x86_64
2017-01-16T20:27:59.622+0800 I CONTROL  [initandlisten] options: { systemLog: { verbosity: 1 } }
2017-01-16T20:27:59.622+0800 D NETWORK  [initandlisten] fd limit hard:4096 soft:1024 max conn: 819
2017-01-16T20:27:59.644+0800 E NETWORK  [initandlisten] listen(): bind() failed errno:98 Address already in use for socket: 0.0.0.0:27017
2017-01-16T20:27:59.644+0800 E NETWORK  [initandlisten]   addr already in use
2017-01-16T20:27:59.644+0800 E STORAGE  [initandlisten] Failed to set up sockets during startup.
2017-01-16T20:27:59.644+0800 I CONTROL  [initandlisten] dbexit:  rc: 48

如有以上提示,即表明安裝成功。

3、啟動

3.1 創建數據庫目錄

Mongodb 需要自建數據庫文件夾

mkdir -p /data/mongodb
mkdir -p /data/mongodb/log
touch /data/mongodb/log/mongodb.log

添加配置文件

新建配置文件:mongodb.conf,通過其進行啟動

vim /etc/mongodb.conf

配置文件參數說明:


mongodb的參數說明:

--dbpath 數據庫路徑(數據文件)

--logpath 日志文件路徑

--master 指定為主機器

--slave 指定為從機器

--source 指定主機器的IP地址

--pologSize 指定日志文件大小不超過64M.因為resync是非常操作量大且耗時,最好通過設置一個足夠大的oplogSize來避免resync(默認的 oplog大小是空閑磁盤大小的5%)。

--logappend 日志文件末尾添加

--port 啟用端口號

--fork 在后臺運行

--only 指定只復制哪一個數據庫

--slavedelay 指從復制檢測的時間間隔

--auth 是否需要驗證權限登錄(用戶名和密碼)

注:mongodb配置文件里面的參數很多,定制特定的需求,請參考官方文檔

配置文件內容:

dbpath=/data/mongodb
logpath=/data/mongodb/log/mongodb.log
logappend=true
port=27017
fork=true
##auth = true # 先關閉, 創建好用戶在啟動

通過配置文件啟動

mongod -f /etc/mongodb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 2814
child process started successfully, parent exiting

若出現上述信息,則表示啟動成功了。

4、進入mongodb-shell

方法:

cd /usr/local/mongodb/bin
./mongo

創建數據庫

[IN] use test
[OUT] switched to db test

創建用戶,設置權限

db.createUser(
    {
        user: "test",
        pwd: "test",
        roles: [ { role: "readWrite", db: "test" } ]
    }
)

更多權限配置請參考:點我

注:在設置好權限后,到/etc/mongodb.conf 將auth改為true,下次在使用對應的數據庫時,則需要進行驗證:db.auth(user,passwd)

5、配置防火墻

將27017端口添加到防火墻中

vi /etc/sysconfig/iptables
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 27017 -j ACCEPT
/etc/init.d/iptables reload

二、PyMongo

1、安裝

pip install pymongo

2、使用

2.1 連接

 (1) 導入
from pymongo import MongoClient

 (2) 連接mongodb
host = localhost
port = 27017

client = MongoClient(host,port)

 (3) 連接數據庫

db = client.test_database

or 

db = client[test_database]

注:當連接的數據庫設置了auth之后,需要這樣連接,不同版本,不同平臺都不一樣,具體見官方文檔

client[test_database].authenticate("user","passwd",mechanism="SCRAM-SHA-1")

(4) 連接數據庫中的某個集合
## 獲取該數據庫中的非系統集合
db.collection_names(include_system_collections=False)

## 連接集合
collection = db[collection_name]
or 
collection = db.collection_name

2.2 增刪改查

很好的一點就是,數據庫不需要先建立,在連接后,如果進行插入數據操作,系統可以自己創建,上面提到過,mongodb的數據,使用的是類似json風格的文檔,在python中即為字典,形如下例:

         insert_data = {
         "author": "Mike",
         "text": "My first blog post!",
         "tags": ["mongodb", "python", "pymongo"],
         "date": datetime.datetime.utcnow()
          }

collection = db[collection_name]

(1)增

在插入一個文檔時,MongoDB會自動給每個文檔增加一個”_id”的鍵,這個鍵是通過復雜計算出來的,不會重復,類似于下面這樣的:

ObjectId('4ea02dfdd483050fe8000001')

那么如何利用ObjectId查詢,這里有一個坑

>>> import pymongo
>>> import time
>>> db = pymongo.Connection("192.168.xx.xx",27017).linuxyan
>>> posts = db.posts
>>> post = {"id": "1",
...         "author": "Mike",
...         "text": "My first blog post!",
...         "tags": ["mongodb", "python", "pymongo"],
...         "date": time.strftime('%Y-%m-%d %H:%M:%S')}
>>> posts.insert(post)
ObjectId('53bd5a5fe138235f74b67563')

#//插入數據成功
#//利用{'author':'Mike'} 測試查詢正常
>>> posts.find_one({'author':'Mike'})
{u'_id': ObjectId('53bd5a5fe138235f74b67563'), u'author': u'Mike',....}

#//利用{'_id':"ObjectId('53bd5a5fe138235f74b67563')"}查詢為空
>>>posts.find_one({'_id':"ObjectId('53bd5a5fe138235f74b67563')"})   

#//如何利用ObjectId來查詢?
>>> from bson import ObjectId
>>> posts.find_one({'_id':ObjectId('53bd5a5fe138235f74b67563')})  
{ u'_id': ObjectId('53bd5a5fe138235f74b67563'), u'author': u'Mike',....}
#//原來ObjectId是一個對象,而不是一個字符串,此時我只能"呵呵",折騰兩個多小時。

增加數據不需要事先定義文檔的機構,每個文檔的結構也可以不一樣

單條插入
result = collection.insert_one(insert_data)
多條插入
result = collection.insert_many(insert_datas)
返回插入id
result.insert_id [單]    
result.insert_ids [多]
(2)查 參考here
無條件查詢
collection.find_one() [單]    
collection.find() [多]
條件查詢
collection.find({"author": "Mike"})    
collection.find_one({"author": "Mike"})
cursor = collection.find({
"$or":[{"cuisine": "Italian", "address.zipcode": "10075"}]
}
)    
[僅顯示cuisine為Italian和address.zipcode為10075的數據。兩個條件只要滿足一個就可以]
區間查詢
d = datetime.datetime(2009, 11, 12, 12)
for post in collection.find({"date": {"$lt": d}}).sort("author"):    
    print post
 $lt 小于
文檔記錄數
collection.count()
數據排序

調用 pymongo.ASCENDING()和pymongo.DESCENDING()來指定是按升降序進行排序

cursor = collection.find().sort([
    ("borough", pymongo.ASCENDING),
    ("address.zipcode", pymongo.ASCENDING)
])
從第幾行開始讀取(SLICE),讀取多少行(LIMIT)
for u in collection.find().skip(2).limit(3): 
    print u
IN
for u in db.users.find({"age":{"$in":(23, 26, 32)}}): print u
for u in db.users.find({"age":{"$nin":(23, 26, 32)}}): print u
是否存在
db.users.find({'sex':{'$exists':True}})  # select * from 集合名 where exists 鍵1
db.users.find({'sex':{'$exists':False}}) # select * from 集合名 where not exists 鍵1
正則表達式查詢
for u in db.users.find({"name" : {"$regex" : r"(?i)user[135]"}}, ["name"]): print u # 查詢出 name 為 user1, user3, user5 的
多級路徑的元素值匹配
Document 采取 JSON-like 這種層級結構,因此我們可以直接用嵌入(Embed)代替傳統關系型數據庫的關聯引用(Reference)。
    MongoDB 支持以 "." 分割的 namespace 路徑,條件表達式中的多級路徑須用引號

# 條件表達式中的多級路徑須用引號,以 "." 分割
    u = 集合名.find_one({"im.qq":12345678})
    # 查詢結果如:{"_id" : ObjectId("4c479885089df9b53474170a"), "name" : "user1", "im" : {"msn" : "user1@hotmail.com", "qq" : 12345678}}
(3)改
origin_data = {"title":"Python and MongoDB",
     "slug":"python-mongodb",
     "author":"SErHo",
     "content":"Python and MongoDB....",
     "tags":["Python","MongoDB"],
     "time":datetime.datetime.now()}
>>> post = posts.find_one({"slug":"python-mongodb"})
>>> post["author"]
u'SErHo'
>>> post["author"] = "HaHa Lu"
>>> post["title"] = "Test Update"
>>> post["title"] = "Test Update"
>>> post["_id"]
ObjectId('4ea0207dd483050fe8000001')
>>> posts.update({"_id":post["_id"]},post)
>>> post = posts.find_one({"_id":post["_id"]})
>>> print post
{u'author': u'HaHa Lu', u'title': u'Test Update',
 u'tags': [u'Python', u'MongoDB'],
 u'content': u'Python and MongoDB....',
 u'time': datetime.datetime(2011, 10, 20, 21, 21, 52, 818000),
 u'_id': ObjectId('4ea0207dd483050fe8000001'),
 u'slug': u'python-mongodb'}

首先我們根據slug來獲得一篇文章,然后可以通過Python字典訪問方法得到鍵的值,然后重新設置,再對post集合進行更新,在對整個集合進行更新時,你得先匹配要更改的文檔,利用_id這個屬性來更新是比較常用的方法,因為你其他改了,這個可改不了。在執行update中最常見的錯誤就是限制的條件找到了多個文檔,如果這樣,數據庫就不會更新這個集合,所有最好使用_id來匹配。

如果只更新一個鍵呢,那就不用這么大費周折了,可以使用”$set”這個修改器,指定一個鍵,如果不存在,就可以創建。比如我要繼續更新上面那篇文章的content,可以這樣做(記住,修改它,必須先找到它,這里我利用上面查詢到的_id值來找):

>>> posts.update({"_id":post["_id"]},{"$set": {"content":"Test Update SET...."}})

MongoDB的修改是很強大的,你可以把數據類型也給改了,比如把tags的數組改成普通的字符串。”$set”過后又想刪除這個鍵,可以使用”$unset”。如果我的這個post里面有一個鍵是views,即文章訪問的次數,我想在每次訪問這個文章后給它的值增加1,這該怎么辦?于是”$inc”修改器出場了,這個可以用來增加已有鍵的值,如果沒有,則創建它,類似的用法是:

>>> posts.update({"_id":post["_id"]},{"$inc":  {"views":1}})

如果想修改tags這個數組里面的內容怎么辦?有一個辦法就是用$set整體修改,但只是改里面的一些元素呢,MongoDB準備好了用于數組的修改器。比如,想要在tags里面加一個”Test”,這需要使用”$push”,它可以在數組末尾添加一個元素:

>>> posts.update({"_id":post["_id"]},{"$push":{"tags":"Test"}})

為了避免加入了重復的,可以將”$push”改為使用”$addToSet”,如果需要添加多個值,可以配合”$each”來使用,這樣就可以添加不重復的進去,如下面:

>>> posts.update({"_id":post["_id"]},{"$addToSet": {"tags":{"$each":["Python","Each"]}}})

(4) 刪

可以把數組看成棧和隊列,使用”$pop”來操作,比如上面的:

>>> posts.update({"_id":post["_id"]},{"$pop":{"tags":1}})

這個會刪除tags里面最后一個,改成-1則刪除第一個。可以使用”$pull”來刪除數組中指定的值,它會刪除數組中所有匹配的值。如何修改其中的一個值呢?可以先刪除掉,再增加一個進去,還有就是直接定位修改。比如tags數組中,”Python”是第一個,想把它改成”python”,可以通過下標直接選擇,就是tags[0],然后使用上面的”$set”等修改器,如果不確定可以使用$來定位:

>>> posts.update({"tags":"MongoDB"},{"$set":{"tags.$":"Hello"}})

這個將先搜索tags中滿足”MongoDB”的,如果找到,就把它修改為”Hello”。可以看到上面的update這個函數已經有兩個參數了,它還有第3個參數upsert,如果設為”True”,則如果沒有找到匹配的文檔,就會在匹配的基礎上新建一個文檔

3、相關操作

注:collection:user
(1) $all: 判斷數組屬性是否包含全部條件。
    db.users.insert({'name':"user3", 'data':[1,2,3,4,5,6,7]})
    db.users.insert({'name':"user4", 'data':[1,2,3]})

    for u in db.users.find({'data':{'$all':[2,3,4]}}): print u
    # 顯示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "name" : "user3", "data" : [ 1, 2, 3, 4, 5, 6, 7 ] }
    注意和 $in 的區別。$in 是檢查目標屬性值是條件表達式中的一員,而 $all 則要求屬性值包含全部條件元素。

  (2) $size: 匹配數組屬性元素數量。
    for u in db.users.find({'data':{'$size':3}}): print u
    # 只顯示匹配此數組數量的: { "_id" : ObjectId("4c47a13bb48cde79c6780df1"), "name" : "user4", "data" : [ 1, 2, 3 ] }

  (3) $type: 判斷屬性類型。
    for u in db.users.find({'t':{'$type':1}}): print u  # 查詢數字類型的
    for u in db.users.find({'t':{'$type':2}}): print u  # 查詢字符串類型的

    類型值:
        double:1
        string: 2
        object: 3
        array: 4
        binary data: 5
        object id: 7
        boolean: 8
        date: 9
        null: 10
        regular expression: 11
        javascript code: 13
        symbol: 14
        javascript code with scope: 15
        32-bit integer: 16
        timestamp: 17
        64-bit integer: 18
        min key: 255
        max key: 127

  (4) $not: 取反,表示返回條件不成立的文檔。
    似乎只能跟正則和 $mod 一起使用????
    # 還不知如何使用

  (5) $unset: 和 $set 相反,表示移除文檔屬性。
    for u in db.users.find({'name':"user1"}): print u
    # 顯示如: { "_id" : ObjectId("4c479885089df9b53474170a"), "name" : "user1", "age" : 15, "address" : [ "address1", "address2" ] }

    db.users.update({'name':"user1"}, {'$unset':{'address':1, 'age':1}})
    for u in db.users.find({'name':"user1"}): print u
    # 顯示如: { "_id" : ObjectId("4c479885089df9b53474170a"), "name" : "user1" }

  (6) $push: 和 $ pushAll 都是向數組屬性添加元素。# 好像兩者沒啥區別
    for u in db.users.find({'name':"user1"}): print u
    # 顯示如: { "_id" : ObjectId("4c479885089df9b53474170a"), "age" : 15, "name" : "user1" }

    db.users.update({'name':"user1"}, {'$push':{'data':1}})
    for u in db.users.find({'name':"user1"}): print u
    # 顯示如: { "_id" : ObjectId("4c479885089df9b53474170a"), "age" : 15, "data" : [ 1 ], "name" : "user1" }

    db.users.update({'name':"user1"}, {'$pushAll':{'data':[2,3,4,5]}})
    for u in db.users.find({'name':"user1"}): print u
    # 顯示如: { "_id" : ObjectId("4c479885089df9b53474170a"), "age" : 15, "data" : [ 1, 2, 3, 4, 5 ], "name" : "user1" }

  (7) $addToSet: 和 $push 類似,不過僅在該元素不存在時才添加 (Set 表示不重復元素集合)。
    db.users.update({'name':"user2"}, {'$unset':{'data':1}})
    db.users.update({'name':"user2"}, {'$addToSet':{'data':1}})
    db.users.update({'name':"user2"}, {'$addToSet':{'data':1}})
    for u in db.users.find({'name':"user2"}): print u
    # 顯示: { "_id" : ObjectId("4c479896089df9b53474170b"), "data" : [ 1 ], "name" : "user2" }

    db.users.update({'name':"user2"}, {'$push':{'data':1}})
    for u in db.users.find({'name':"user2"}): print u
    # 顯示: { "_id" : ObjectId("4c479896089df9b53474170b"), "data" : [ 1, 1 ], "name" : "user2" }

    要添加多個元素,使用 $each。
    db.users.update({'name':"user2"}, {'$addToSet':{'data':{'$each':[1,2,3,4]}}})
    for u in db.users.find({'name':"user2"}): print u
    # 顯示: {u'age': 12, u'_id': ObjectId('4c479896089df9b53474170b'), u'data': [1, 1, 2, 3, 4], u'name': u'user2'}
    # 貌似不會自動刪除重復

  (8) $each 添加多個元素用。
    db.users.update({'name':"user2"}, {'$unset':{'data':1}})
    db.users.update({'name':"user2"}, {'$addToSet':{'data':1}})
    for u in db.users.find({'name':"user2"}): print u
    # 顯示: { "_id" : ObjectId("4c479896089df9b53474170b"), "data" : [ 1 ], "name" : "user2" }

    db.users.update({'name':"user2"}, {'$addToSet':{'data':{'$each':[1,2,3,4]}}})
    for u in db.users.find({'name':"user2"}): print u
    # 顯示: {u'age': 12, u'_id': ObjectId('4c479896089df9b53474170b'), u'data': [1, 2, 3, 4], u'name': u'user2'}

    db.users.update({'name':"user2"}, {'$addToSet':{'data':[1,2,3,4]}})
    for u in db.users.find({'name':"user2"}): print u
    # 顯示: { "_id" : ObjectId("4c479896089df9b53474170b"), "data" : [ 1, 2, 3, 4, [ 1, 2, 3, 4 ] ], "name" : "user2" }

    db.users.update({'name':"user2"}, {'$unset':{'data':1}})
    db.users.update({'name':"user2"}, {'$addToSet':{'data':[1,2,3,4]}})
    for u in db.users.find({'name':"user2"}): print u
    # 顯示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ [1, 2, 3, 4] ], "name" : "user2" }

  (9) $pop: 移除數組屬性的元素(按數組下標移除),$pull 按值移除,$pullAll 移除所有符合提交的元素。
    db.users.update({'name':"user2"}, {'$unset':{'data':1}})
    db.users.update({'name':"user2"}, {'$addToSet':{'data':{'$each':[1, 2, 3, 4, 5, 6, 7, 2, 3 ]}}})
    for u in db.users.find({'name':"user2"}): print u
    # 顯示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 1, 2, 3, 4, 5, 6, 7, 2, 3 ], "name" : "user2" }

    db.users.update({'name':"user2"}, {'$pop':{'data':1}}) # 移除最后一個元素
    for u in db.users.find({'name':"user2"}): print u
    # 顯示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 1, 2, 3, 4, 5, 6, 7, 2 ], "name" : "user2" }

    db.users.update({'name':"user2"}, {'$pop':{'data':-1}}) # 移除第一個元素
    for u in db.users.find({'name':"user2"}): print u
    # 顯示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 2, 3, 4, 5, 6, 7, 2 ], "name" : "user2" }

    db.users.update({'name':"user2"}, {'$pull':{'data':2}}) # 移除全部 2
    for u in db.users.find({'name':"user2"}): print u
    # 顯示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 3, 4, 5, 6, 7 ], "name" : "user2" }

    db.users.update({'name':"user2"}, {'$pullAll':{'data':[3,5,6]}}) # 移除 3,5,6
    for u in db.users.find({'name':"user2"}): print u
    # 顯示: { "_id" : ObjectId("4c47a133b48cde79c6780df0"), "data" : [ 4, 7 ], "name" : "user2" }

  (10) $where: 用 JS 代碼來代替有些丑陋的 $lt、$gt。
    MongoDB 內置了 Javascript Engine (SpiderMonkey)。可直接使用 JS Expression,甚至使用 JS Function 寫更復雜的 Code Block。

    db.users.remove() # 刪除集合里的所有記錄
    for i in range(10):
        db.users.insert({'name':"user" + str(i), 'age':i})
    for u in db.users.find(): print u
    # 顯示如下:
    { "_id" : ObjectId("4c47b3372a9b2be866da226e"), "name" : "user0", "age" : 0 }
    { "_id" : ObjectId("4c47b3372a9b2be866da226f"), "name" : "user1", "age" : 1 }
    { "_id" : ObjectId("4c47b3372a9b2be866da2270"), "name" : "user2", "age" : 2 }
    { "_id" : ObjectId("4c47b3372a9b2be866da2271"), "name" : "user3", "age" : 3 }
    { "_id" : ObjectId("4c47b3372a9b2be866da2272"), "name" : "user4", "age" : 4 }
    { "_id" : ObjectId("4c47b3372a9b2be866da2273"), "name" : "user5", "age" : 5 }
    { "_id" : ObjectId("4c47b3372a9b2be866da2274"), "name" : "user6", "age" : 6 }
    { "_id" : ObjectId("4c47b3372a9b2be866da2275"), "name" : "user7", "age" : 7 }
    { "_id" : ObjectId("4c47b3372a9b2be866da2276"), "name" : "user8", "age" : 8 }
    { "_id" : ObjectId("4c47b3372a9b2be866da2277"), "name" : "user9", "age" : 9 }

    for u in db.users.find({"$where":"this.age > 7 || this.age < 3"}): print u
    # 顯示如下:
    {u'age': 0.0, u'_id': ObjectId('4c47b3372a9b2be866da226e'), u'name': u'user0'}
    {u'age': 1.0, u'_id': ObjectId('4c47b3372a9b2be866da226f'), u'name': u'user1'}
    {u'age': 2.0, u'_id': ObjectId('4c47b3372a9b2be866da2270'), u'name': u'user2'}
    {u'age': 8.0, u'_id': ObjectId('4c47b3372a9b2be866da2276'), u'name': u'user8'}
    {u'age': 9.0, u'_id': ObjectId('4c47b3372a9b2be866da2277'), u'name': u'user9'}

    for u in db.users.find().where("this.age > 7 || this.age < 3"): print u
    # 顯示如下:
    {u'age': 0.0, u'_id': ObjectId('4c47b3372a9b2be866da226e'), u'name': u'user0'}
    {u'age': 1.0, u'_id': ObjectId('4c47b3372a9b2be866da226f'), u'name': u'user1'}
    {u'age': 2.0, u'_id': ObjectId('4c47b3372a9b2be866da2270'), u'name': u'user2'}
    {u'age': 8.0, u'_id': ObjectId('4c47b3372a9b2be866da2276'), u'name': u'user8'}
    {u'age': 9.0, u'_id': ObjectId('4c47b3372a9b2be866da2277'), u'name': u'user9'}

    # 使用自定義的 function, javascript語法的
    for u in db.users.find().where("function() { return this.age > 7 || this.age < 3;}"): print u
    # 顯示如下:
    {u'age': 0.0, u'_id': ObjectId('4c47b3372a9b2be866da226e'), u'name': u'user0'}
    {u'age': 1.0, u'_id': ObjectId('4c47b3372a9b2be866da226f'), u'name': u'user1'}
    {u'age': 2.0, u'_id': ObjectId('4c47b3372a9b2be866da2270'), u'name': u'user2'}
    {u'age': 8.0, u'_id': ObjectId('4c47b3372a9b2be866da2276'), u'name': u'user8'}
    {u'age': 9.0, u'_id': ObjectId('4c47b3372a9b2be866da2277'), u'name': u'user9'}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,687評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,682評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,011評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,183評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,714評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,435評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,665評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,838評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,379評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,627評論 2 380

推薦閱讀更多精彩內容