pymongo的数组操作
数据样例
{ "_id" : ObjectId("5e67343f00850012ec08ad3e"), "river" : [ "长江", "黄河", "淮河" ] } { "_id" : ObjectId("5e67343f00850012ec08ad3f"), "river" : [ "长江", "松花江", "嘉陵江" ] }
一:普通包含查询
def get_all(self):
# 查询数组中包含长江的所有文档 result_cursor = self.db["test_info"].find({"river":"长江"}) temp = list() for result in result_cursor: temp.append(result) print(temp) return temp [{'_id': ObjectId('5e67343f00850012ec08ad3e'), 'river': ['长江', '黄河', '淮河']}, {'_id': ObjectId('5e67343f00850012ec08ad3f'), 'river': ['长江', '松花江', '嘉陵江']}]
二:$all 包含查询
数据样例
{ "_id" : ObjectId("5e67343f00850012ec08ad3e"), "river" : [ "长江", "黄河", "淮河" ] } { "_id" : ObjectId("5e67343f00850012ec08ad3f"), "river" : [ "长江", "松花江", "嘉陵江" ] } { "_id" : ObjectId("5e6737552a89d7c2fc0cd5d1"), "river" : [ "长江", "黄河", "黄浦江" ] }
需要查询数组里面包含长江和黄河的所有文档
def get_all(self): result_cursor = self.db["test_info"].find({"river":{"$all":["长江","黄河"]}}) temp = list() for result in result_cursor: temp.append(result) print(temp) return temp [{'_id': ObjectId('5e67343f00850012ec08ad3e'), 'river': ['长江', '黄河', '淮河']}, {'_id': ObjectId('5e6737552a89d7c2fc0cd5d1'), 'river': ['长江', '黄河', '黄浦江']}]
普通查询的 {"river":"长江"} 其实就相当于 {"river":{"$all":["长江"]}
三:指定位置(下标)查询 数组名称.index
要查询数组最后一位元素是黄浦江的文档
def get_all(self): result_cursor = self.db["test_info"].find({"river.2":"黄浦江"}) temp = list() for result in result_cursor: temp.append(result) print(temp) return temp [{'_id': ObjectId('5e6737552a89d7c2fc0cd5d1'), 'river': ['长江', '黄河', '黄浦江']}]
四:指定长度查询 $size
查询数组长度为3的所有文档
def get_all_size(self): result_cursor = self.db["test_info"].find({"river":{"$size":3}}) temp = list() for result in result_cursor: temp.append(result) print(temp) return temp [{'_id': ObjectId('5e67343f00850012ec08ad3e'), 'river': ['长江', '黄河', '淮河']}, {'_id': ObjectId('5e67343f00850012ec08ad3f'), 'river': ['长江', '松花江', '嘉陵江']}, {'_id': ObjectId('5e6737552a89d7c2fc0cd5d1'), 'river': ['长江', '黄河', '黄浦江']}]
五:返回数组的一个子集 $slice find的第二个查询参数
返回查询结果数组里面的前两个元素
def get_all_size(self): result_cursor = self.db["test_info"].find({},{"river":{"$slice":2}}) temp = list() for result in result_cursor: temp.append(result) print(temp) return temp [{'_id': ObjectId('5e67343f00850012ec08ad3e'), 'river': ['长江', '黄河']}, {'_id': ObjectId('5e67343f00850012ec08ad3f'), 'river': ['长江', '松花江']}, {'_id': ObjectId('5e6737552a89d7c2fc0cd5d1'), 'river': ['长江', '黄河']}]
def get_all_size(self): result_cursor = self.db["test_info"].find({},{"river":{"$slice":-1}}) temp = list() for result in result_cursor: temp.append(result) print(temp) return temp [ {'_id': ObjectId('5e67343f00850012ec08ad3e'), 'river': ['淮河']}, {'_id': ObjectId('5e67343f00850012ec08ad3f'), 'river': ['嘉陵江']}, {'_id': ObjectId('5e6737552a89d7c2fc0cd5d1'), 'river': ['黄浦江']}]
返回查询结果数组里面的最后一个元素
$slice可以接受偏移量,跳过指定数量的元素,返回指定数量的元素
def get_all_size(self): result_cursor = self.db["test_info"].find({},{"river":{"$slice":[1,2]}}) temp = list() for result in result_cursor: temp.append(result) print(temp) return temp [ {'_id': ObjectId('5e67343f00850012ec08ad3e'), 'river': ['黄河', '淮河']}, {'_id': ObjectId('5e67343f00850012ec08ad3f'), 'river': ['松花江', '嘉陵江']}, {'_id': ObjectId('5e6737552a89d7c2fc0cd5d1'), 'river': ['黄河', '黄浦江']}]
跳过数组里面的第一个元素,返回跳过后的前两个元素:如果跳过第一个元素后,剩下的元素不够两个,就返回剩下的所有元素
数据格式如下
{ "_id" : ObjectId("5e688d3a2a89d7c2fc0d64ee"), "t_id" : "1", "data" : [ { "time" : ISODate("2020-03-07T19:59:00.000Z"), "x" : "100" }, { "time" : ISODate("2020-03-08T19:59:00.000Z"), "x" : "200" }, { "time" : ISODate("2020-03-09T19:59:00.000Z"), "x" : "300" }, { "time" : ISODate("2020-03-10T19:59:00.000Z"), "x" : "400" }, { "time" : ISODate("2020-03-11T19:59:00.000Z"), "x" : "500" } ] }
数组里面的元素,返回指定时间段内的数据,返回 2020-03-07-2020-03-11之间的data数据
def get_list_time_range(self): if self.connect_result: s_time = datetime.datetime(2020,3,7,0,0,0) e_time = datetime.datetime(2020,3,11,23,59,59) match_dict = {"$match":{"t_id":"1"}} unwind_dict = {"$unwind":"$data"} project_dict = {"$project":{"_id":0,"data":1}} match_dict2 = {"$match":{"data.time":{"$gte":s_time,"$lte":e_time}}} result = self.db["test_info"].aggregate([match_dict,unwind_dict,project_dict,match_dict2]) temp_list = list() print(result) for info in result: info = info["data"] print(info) temp_list.append((info["x"],100)) print(temp_list)
结果
<pymongo.command_cursor.CommandCursor object at 0x0000000002FF3D88> {'time': datetime.datetime(2020, 3, 7, 19, 59), 'x': '100'} {'time': datetime.datetime(2020, 3, 8, 19, 59), 'x': '200'} {'time': datetime.datetime(2020, 3, 9, 19, 59), 'x': '300'} {'time': datetime.datetime(2020, 3, 10, 19, 59), 'x': '400'} {'time': datetime.datetime(2020, 3, 11, 19, 59), 'x': '500'} [('100', 100), ('200', 100), ('300', 100), ('400', 100), ('500', 100)]
六,数组插入数据
$push:将内容插入指定的数组里面,不论内容是否相同,不进行去重,均执行插入
# 数据样式 { "_id" : ObjectId("5e8eba932a89d7c2fc29ebb3"), "name" : "a", "data_list" : [] }
需求一:给 data_list插入三组一样的数据
def push_method(self): result = self.db["test1"].update({"name":"a"},{"$push":{"data_list":{"city":"西安"}}}) print(result) # 结果 {'n': 1, 'nModified': 1, 'ok': 1.0, 'updatedExisting': True}
执行三次后的结果
{ "_id" : ObjectId("5e8eba932a89d7c2fc29ebb3"), "name" : "a", "data_list" : [ { "city" : "西安" }, { "city" : "西安" }, { "city" : "西安" } ] }
结果可以看出,相同的三组数据都可以插入,那么怎么让相同的数据,不能够插入呢?
# 数据格式 { "_id" : ObjectId("5e8eba932a89d7c2fc29ebb3"), "name" : "a", "data_list" : [] }
$addToSet:将内容插入指定数组,内容相同就不执行插入,去重
执行三次的打印结果
def add_to_set(self): result = self.db["test1"].update({"name": "a"}, {"$addToSet": {"data_list": {"city": "西安"}}}) print(result) # 结果 {'n': 1, 'nModified': 1, 'ok': 1.0, 'updatedExisting': True} {'n': 1, 'nModified': 0, 'ok': 1.0, 'updatedExisting': True} {'n': 1, 'nModified': 0, 'ok': 1.0, 'updatedExisting': True}
执行三次的数据样式
/* 1 */ { "_id" : ObjectId("5e8eba932a89d7c2fc29ebb3"), "name" : "a", "data_list" : [ { "city" : "西安" } ] }
$pushAll:版本4.0.10已经作废,可使用 push代替,插入一组数据
# 数据样式 { "_id" : ObjectId("5e8eba932a89d7c2fc29ebb3"), "name" : "a", "data_list" : [] }
MongoDB shell version v4.0.10
报错:
pymongo.errors.WriteError: Unknown modifier: $pushAll
def push_many_method(self): result = self.db["test1"].update({"name": "a"}, {"$push": {"data_list":[{"city": "西安"},{"city": "南京"}]}}) print(result) # 结果 {'n': 1, 'nModified': 1, 'ok': 1.0, 'updatedExisting': True}
/* 1 */ { "_id" : ObjectId("5e8eba932a89d7c2fc29ebb3"), "name" : "a", "data_list" : [ [ { "city" : "西安" }, { "city" : "南京" } ] ] }
可以看出,push也可以一次性,插入多组数据。
https://blog.csdn.net/oxgos/article/details/78837931
https://www.cnblogs.com/xuliuzai/p/10331524.html
# TODO