Pymongo入门学习笔记(三)


升级数据(Update)

使用Pymongo进行数据的update,同样有两种方法可用,分别为update_one()update_many()。顾名思义,update_one()只升级一条文档,update_many()升级所有符合查询条件的文档。

注意:_id字段无法被升级!

升级指定单个字段

MongoDB提供了升级操作符(update operators)来进行升级字段的操作,比如$set操作符,可以用来修改一个字段的值。有些操作符,比如$set,如果字段不存在的话,会创建这个字段。

详情可查看官网关于查询操作符的页面。

1
2
3
4
5
6
7
8
9
result = db.restaurants.update_one(
{"name": "Juni"},
{
"$set": {
"cuisine": "American (New)"
},
"$currentDate": {"lastModified": True}
}
)

如上代码进行的操作,将会升级数据库中第一个”name”字段为”Juni”的文档,使用$set操作符修改了cuisine字段,然后使用$currentDate操作符升级了lastModified字段。

操作将会返回一个UpdateResult对象,其中包含了修改了的文档数目。可以通过以下代码查看:

1
2
3
4
5
6
7
result.matched_count
# 返回值:
# 1

result.modified_count
# 返回值:
# 1

如果要修改的字段被嵌入在文档或列表中,可以使用点号。例如:

1
2
3
4
result = db.restaurants.update_one(
{"restaurant_id": "41156888"},
{"$set": {"address.street": "East 31st Street"}}
)

上面的操作升级了address文档中的street字段。

升级多个文档

和升级单个文档类似,可以使用update_many()方法来升级符合查询条件的多个文档。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
result = db.restaurants.update_many(
{"address.zipcode": "10016", "cuisine": "Other"},
{
"$set": {"cuisine": "Category To Be Determined"},
"$currentDate": {"lastModified": True}
}
)

# 查询match的文档数量
print(result.matched_count)
# 返回值应为 20

# 查询修改的文档数量
print(result.modified_count)
# 返回值应为 20

替换文档

在一个文档中,除了 _id 字段都可被替换。被替换的文档的结构可以和原文档不同。

注意:
文档替换之后,新的文档将不再包含原文档中的字段!

例如,在下面的替换操作之后,新的文档将只包含 _id 字段,name 字段, address 字段等。其余原文档中的字段不再存在。

1
2
3
4
5
6
7
8
9
10
11
12
result = db.restaurants.replace_one(
{"restaurant_id": "41704620"},
{
"name": "Vella 2",
"address": {
"coord": [-73.9557413, 40.7720266],
"building": "1480",
"street": "2 Avenue",
"zipcode": "10075"
}
}
)

移除数据(Remove)

从集合中移除文档

Pymongo提供了 delete_one()delete_many() 两种方法,来从集合中移除文档。它们的使用是类似的。

通过下面的操作,可以移除符合查询条件的文档,并打印移除文档的数量。

1
2
3
4
5
result = db.restaurants.delete_many({"borough": "Manhattan"})

# 打印移除文档的数量
print(result.deleted_count)
# 移除的文档数量: 10259

如果不指定条件,那么将会删除所有文档。如

1
result = db.restaurants.delete_many({})

移除集合

如果仅仅移除集合中的所有文档,操作完成之后集合仍然存在。所以更有效率的方式是直接移除该集合,可以使用 drop() 方法实现该操作。

1
db.restaurants.drop()

数据聚合(Aggregat)

MongoDB中的聚合操作主要用于处理数据,比如统计平均值、求和等,返回值为计算后的数据结果。有点类似于sql与剧中的count(*)。例如:

1
2
3
4
5
cursor = db.restaurants.aggregate(
[
{"$group": {"_id": "$borough", "count": {"$sum": 1}}}
]
)

以上操作先根据 borough 字段分组,然后计算了每一组中文档的数目。返回值如下:

1
2
3
4
5
6
{u'count': 969, u'_id': u'Staten Island'}
{u'count': 6086, u'_id': u'Brooklyn'}
{u'count': 10259, u'_id': u'Manhattan'}
{u'count': 5656, u'_id': u'Queens'}
{u'count': 2338, u'_id': u'Bronx'}
{u'count': 51, u'_id': u'Missing'}

管道(Pipeline)

管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。

MongoDB中的聚合管道将MongoDB文档在一个管道处理完毕后,将结果传递给下一个管道处理。管道操作是可以重复的。

聚合中常用的几个管道操作有:

  • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
  • $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
  • $limit:用来限制MongoDB聚合管道返回的文档数。
  • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
  • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
  • $group:将集合中的文档分组,可用于统计结果。
  • $sort:将输入文档排序后输出。
  • $geoNear:输出接近某一地理位置的有序文档。

实例

除了上面进行分组并计数的操作外,另一个常见的操作是查询符合条件的文档,再对符合条件的文档进行分组统计。既然管道操作是可以重复的,那么便可以使用两个管道操作来实现。

1
2
3
4
5
6
cursor = db.restaurants.aggregate(
[
{"$match": {"borough": "Queens", "cuisine": "Brazilian"}},
{"$group": {"_id": "$address.zipcode", "count": {"$sum": 1}}}
]
)

索引(Index)

索引通常能够极大的提高查询效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。而这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可能会花费几十秒甚至几分钟。

索引是一种特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库中一列或多列的值进行排序的一种结构。

使用Pymongo,可以使用 create_index() 方法建立数据库索引。

建立单字段索引

如下,可以对 “cuisine” 字段建立一个升序索引。

1
2
import pymongo
db.restaurants.create_index([("cuisine", pymongo.ASCENDING)])

使用pymongo.ASCENDING创建升序索引
使用pymongo.DESCENDING创建降序索引

建立多字段混合索引

如下,创建对 “cuisine” 字段和 “address.zipcode” 字段的混合索引。索引将会首先对 “cuisine” 字段进行升序排列,在每个 “cuisine” 字段中,依据“address.zipcode”字段进行降序排列。

1
2
3
4
5
import pymongo
db.restaurants.create_index([
("cuisine", pymongo.ASCENDING),
("address.zipcode", pymongo.DESCENDING)
])

The End.

谢谢支持!
0%