使用pymongo进行不同的搜索条件(AND/OR/部分匹配/范围搜索)

文章的覆盖范围

在这篇文章中,介绍了使用Python连接mongodb后使用find函数的各种搜索方法。
1. AND
2. OR
3. 部分匹配
4. 前向匹配
5. 后向匹配
6. 范围搜索(BETWEEN)

如果您想了解有关MongoDB的启动和pymongo安装的方法,请参阅以下文章链接:
https://qiita.com/bc_yuuuuuki/items/2b92598434f6cc320112

准备数据。

以下是准备好的MongoDB数据。

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB
> show collections
employee
log
salary
> db.salary.find()
{ "_id" : ObjectId("5d4acf84de925ae437e2c124"), "name" : "佐藤", "salary" : 450000, "depId" : "A0001" }
{ "_id" : ObjectId("5d4acf84de925ae437e2c125"), "name" : "田中", "salary" : 500000, "depId" : "A0001" }
{ "_id" : ObjectId("5d4f814c950945628d663d95"), "name" : "加藤", "salary" : 400000, "depId" : "B0001" }
{ "_id" : ObjectId("5d4f814c950945628d663d96"), "name" : "松井", "salary" : 500000, "depId" : "C0001" }
{ "_id" : ObjectId("5d5179f76427f268db46299f"), "name" : "山田", "salary" : 500000, "depId" : "A0002" }
{ "_id" : ObjectId("5d5216ab61aa9ee6159ad4d8"), "name" : "山田", "salary" : 300000, "depId" : "C0002" }

多种搜索方法

由于搜索方法与MongoDB命令相差较大,因此将在比较MongoDB命令的基础上进行说明。
以下是使用pymongo库的代码内容。

from pymongo import MongoClient
from pymongo import DESCENDING
from pymongo import ASCENDING
from matplotlib import pyplot

class MongoFindSample(object):

    def __init__(self, dbName, collectionName):
        self.client = MongoClient()
        self.db = self.client[dbName]
        self.collection = self.db.get_collection(collectionName)

    def find_one(self, projection=None,filter=None, sort=None):
        return self.collection.find_one(projection=projection,filter=filter,sort=sort)

    def find(self, projection=None,filter=None, sort=None):
        return self.collection.find(projection=projection,filter=filter,sort=sort)

    def count_documents(self, filter=None):
        return self.collection.count_documents(filter)


mongo = MongoFindSample('test', 'salary')

关于AND的用法

从”salary”集合中获取name字段为”山田”且depId字段为”C0002″的数据。
首先,使用mongodb命令。

> db.salary.find({$and:[{'name':'山田'},{'depId':'C0002'}]})
{ "_id" : ObjectId("5d5216ab61aa9ee6159ad4d8"), "name" : "山田", "salary" : 300000, "depId" : "C0002" }

下一步是使用pymongo的写法

result1 = mongo.find(filter={'$and':[{'name':'山田'},{'depId':'C0002'}]})
for doc in result1:
    print(doc)

执行结果

{'_id': ObjectId('5d5216ab61aa9ee6159ad4d8'), 'name': '山田', 'salary': 300000, 'depId': 'C0002'}

关于AND,唯一的区别是是否用单引号引起来。

OR的使用方法

从“salary”集合中获取name字段为“山田”或depId字段为“B0001”的数据。首先,使用mongodb命令。

> db.salary.find({$or:[{'name':'山田'},{'depId':'B0001'}]})
{ "_id" : ObjectId("5d4f814c950945628d663d95"), "name" : "加藤", "salary" : 400000, "depId" : "B0001" }
{ "_id" : ObjectId("5d5179f76427f268db46299f"), "name" : "山田", "salary" : 500000, "depId" : "A0002" }
{ "_id" : ObjectId("5d5216ab61aa9ee6159ad4d8"), "name" : "山田", "salary" : 300000, "depId" : "C0002" }

使用pymongo的方法

result1 = mongo.find(filter={'$or':[{'name':'山田'},{'depId':'B0001'}]})
for doc in result1:
    print(doc)

程序执行结果

{'_id': ObjectId('5d4f814c950945628d663d95'), 'name': '加藤', 'salary': 400000, 'depId': 'B0001'}
{'_id': ObjectId('5d5179f76427f268db46299f'), 'name': '山田', 'salary': 500000, 'depId': 'A0002'}
{'_id': ObjectId('5d5216ab61aa9ee6159ad4d8'), 'name': '山田', 'salary': 300000, 'depId': 'C0002'}

OR与AND一样,只是在周围加上或不加上单引号的区别。

部分一致的使用方法

我会尝试获取包含”name”中的”田”的数据。

> db.salary.find({"name":/田/}))
{ "_id" : ObjectId("5d4acf84de925ae437e2c125"), "name" : "田中", "salary" : 500000, "depId" : "A0001" }
{ "_id" : ObjectId("5d5179f76427f268db46299f"), "name" : "山田", "salary" : 500000, "depId" : "A0002" }
{ "_id" : ObjectId("5d5216ab61aa9ee6159ad4d8"), "name" : "山田", "salary" : 300000, "depId" : "C0002" }

下一步是pymongo的用法。

result1 = mongo.find(filter={'name':{'$regex':'田'}})
for doc in result1:
    print(doc)

执行结果

{'_id': ObjectId('5d4acf84de925ae437e2c125'), 'name': '田中', 'salary': 500000, 'depId': 'A0001'}
{'_id': ObjectId('5d5179f76427f268db46299f'), 'name': '山田', 'salary': 500000, 'depId': 'A0002'}
{'_id': ObjectId('5d5216ab61aa9ee6159ad4d8'), 'name': '山田', 'salary': 300000, 'depId': 'C0002'}

これは書き方がかなり違いますね。
pymongoの方の書き方は”name”に対して正規表現を使いますというような書き方になっています。
また、正規表現のパターンの前後のスラッシュもpymongoでは不要なようです。

一致的使用方法

首先尝试获取以”depId”开头的数据。
先从mongodb的命令开始。

> db.salary.find({"depId":/^A/})
{ "_id" : ObjectId("5d4acf84de925ae437e2c124"), "name" : "佐藤", "salary" : 450000, "depId" : "A0001" }
{ "_id" : ObjectId("5d4acf84de925ae437e2c125"), "name" : "田中", "salary" : 500000, "depId" : "A0001" }
{ "_id" : ObjectId("5d5179f76427f268db46299f"), "name" : "山田", "salary" : 500000, "depId" : "A0002" }

下一步是学习如何使用Pymongo。

result1 = mongo.find(filter={'depId':{'$regex':'^A'}})
for doc in result1:
    print(doc)

执行结果

{'_id': ObjectId('5d4acf84de925ae437e2c124'), 'name': '佐藤', 'salary': 450000, 'depId': 'A0001'}
{'_id': ObjectId('5d4acf84de925ae437e2c125'), 'name': '田中', 'salary': 500000, 'depId': 'A0001'}
{'_id': ObjectId('5d5179f76427f268db46299f'), 'name': '山田', 'salary': 500000, 'depId': 'A0002'}

如果前面相同,就需要加上一个“^”。

後方一致的用法

让我们尝试获取以 “depId” 为结尾的等于 “2” 的数据。
首先,使用 MongoDB 的命令行操作。

> db.salary.find({"depId":/2$/})
{ "_id" : ObjectId("5d5179f76427f268db46299f"), "name" : "山田", "salary" : 500000, "depId" : "A0002" }
{ "_id" : ObjectId("5d5216ab61aa9ee6159ad4d8"), "name" : "山田", "salary" : 300000, "depId" : "C0002" }

下一个是pymongo的使用方法。

result = mongo.find(filter={'depId':{'$regex':'2$'}})
for doc in result:
    print(doc)

执行结果

{'_id': ObjectId('5d5179f76427f268db46299f'), 'name': '山田', 'salary': 500000, 'depId': 'A0002'}
{'_id': ObjectId('5d5216ab61aa9ee6159ad4d8'), 'name': '山田', 'salary': 300000, 'depId': 'C0002'}

後方一致の場合は末尾に$マークが必要です。

范围搜索(在…之间)

因为MongoDB似乎没有BETWEEN操作符,所以我们需要使用AND条件来进行组合查询。让我们尝试获取salary字段在300000以上且400000以下的数据。

> db.salary.find({$and:[{'salary':{$gte:300000}},{'salary':{$lte:400000}}]})
{ "_id" : ObjectId("5d4f814c950945628d663d95"), "name" : "加藤", "salary" : 400000, "depId" : "B0001" }
{ "_id" : ObjectId("5d5216ab61aa9ee6159ad4d8"), "name" : "山田", "salary" : 300000, "depId" : "C0002" }

下面是pymongo的用法。

result1 = mongo.find(filter={'$and':[{'salary':{'$gte':300000}},{'salary':{'$lte':400000}}]})
for doc in result1:
    print(doc)

执行结果

{'_id': ObjectId('5d4f814c950945628d663d95'), 'name': '加藤', 'salary': 400000, 'depId': 'B0001'}
{'_id': ObjectId('5d5216ab61aa9ee6159ad4d8'), 'name': '山田', 'salary': 300000, 'depId': 'C0002'}

真是很长啊。。用下面的写法也能得到相同的结果。

> db.salary.find({'salary':{$gte:300000,$lte:400000}})
{ "_id" : ObjectId("5d4f814c950945628d663d95"), "name" : "加藤", "salary" : 400000, "depId" : "B0001" }
{ "_id" : ObjectId("5d5216ab61aa9ee6159ad4d8"), "name" : "山田", "salary" : 300000, "depId" : "C0002" }
result1 = mongo.find(filter={'salary':{'$gte':300000,'$lte':400000}})

我不清楚内部的运作,但是这个更简洁易懂。

感想是我的思考和感受所产生的。

部分一致以外はmongodbのコマンドと同じものをpymongoで使えました。
ANDのは複数の書き方が出来るみたいなので、違いを細かく調べる必要がありそうです。

有关文章

    Pythonでmongodbを操作する~その1~
    Pythonでmongodbを操作する~その2:find編~
    Pythonでmongodbを操作する~その3:update編~
    Pythonでmongodbを操作する~その4:insert編~
    Pythonでmongodbを操作する~その5:delete編~

bannerAds