面试题答案
一键面试索引策略优化
- 分析查询字段:确定经常用于全文搜索的字段,例如标题、正文等。对这些字段创建合适的索引。
- 单字段索引:如果经常基于某个字段搜索,比如
title
字段,可以创建单字段索引。
from pymongo import MongoClient client = MongoClient('mongodb://localhost:27017/') db = client['your_database'] collection = db['your_collection'] collection.create_index([('title', 1)])
- 复合索引:如果多个字段联合查询,例如
title
和content
,可以创建复合索引。
collection.create_index([('title', 1), ('content', 1)])
- 单字段索引:如果经常基于某个字段搜索,比如
- 文本索引:对于全文搜索,使用MongoDB的文本索引更为合适。它支持更复杂的搜索语法,并且能处理多种语言。
collection.create_index([('content', 'text')])
- 多语言文本索引:如果数据包含多种语言,可以在创建文本索引时指定语言覆盖。
collection.create_index([('content', 'text')], default_language='english', language_override='language_field')
查询优化
- 减少返回字段:只返回需要的字段,避免返回整个文档,减少网络传输和处理的数据量。
result = collection.find({'title': {'$regex': 'keyword'}}, {'title': 1, '_id': 0})
- 使用合适的查询操作符:根据搜索需求选择合适的操作符。对于文本索引,使用
$text
操作符进行全文搜索。result = collection.find({'$text': {'$search': 'keyword'}})
数据库配置优化
- 增加内存分配:确保MongoDB有足够的内存来缓存数据和索引,减少磁盘I/O。可以通过修改MongoDB配置文件中的
storage.wiredTiger.engineConfig.cacheSizeGB
参数来调整内存大小。 - 分片:当数据量非常大时,考虑对数据进行分片。这可以将数据分布在多个服务器上,提高查询性能。
- 启用分片:在MongoDB中,首先要启用分片功能。
mongo sh.enableSharding("your_database")
- 指定分片键:选择合适的字段作为分片键,例如
user_id
。
sh.shardCollection("your_database.your_collection", {"user_id": 1})
代码优化
- 批量操作:如果有多个插入或更新操作,使用批量操作减少与数据库的交互次数。
- 批量插入:
data = [{"title": "doc1", "content": "content1"}, {"title": "doc2", "content": "content2"}] collection.insert_many(data)
- 批量更新:
updates = [{"q": {"title": "doc1"}, "u": {"$set": {"content": "new_content1"}}}, {"q": {"title": "doc2"}, "u": {"$set": {"content": "new_content2"}}}] collection.bulk_write([pymongo.UpdateOne(u["q"], u["u"]) for u in updates])
- 连接池管理:使用连接池来管理与MongoDB的连接,避免频繁创建和销毁连接。
pymongo
默认已经实现了连接池,但是在高并发场景下可以进一步优化连接池的配置。from pymongo import MongoClient client = MongoClient('mongodb://localhost:27017/', maxPoolSize=100, minPoolSize=10)