刚刚接触MongoDB,就要在非常大的数据库中查找字段:这些数据库中存储的都是文书信息,需要在这些文书中提取关键词,并返回这条记录。
此前用的手段是正则表达式,例如从学生列表中找到叫joe的:
db.student.find({name:{$regex:/joe/}}
或者
db.student.find({name:/joe/})
与mysql对比的话表格如下:
MySQL | MongoDB |
---|---|
select * from student where name like ’%joe%’ | db.student.find({name:{$regex:/joe/}}) |
select * from student where name regexp ’joe’ | db.student.find({name:/joe/}) |
这样可以基本实现内容的模糊匹配,但是当数据量比较大的时候速度就成了问题。亲身经历在1600万条文书数据库中检索所有文书是否包括一个字段的时间大约就是30s。如果要检索数万条字段时时间可以说相当感人了。
然而今天意外捣鼓捣鼓,发现了索引
的妙用。
“真香”警告……
解决办法:将数据库所有记录中存放“content”设置索引,相当于“content”中的每个字段都被放入了排上了号,变成了可以查询的“字典”。
速度可以快到60~100倍。
"真香"实例:
- 创建索引:
db.auction_sh_full_done_person_content_part_10000.createIndex({content:"text"})
查询命令:
db.auction_sh_full_done_person_content_part_10000.find({$text:{$search:"张乙娥"}})
大约用了0.009s
注:集合auction_sh_full_done_person_content_part_10000
存放了10.0k数据。
- 获得索引
db.auction_sh_full_done_person_content_part_10000.getIndexes()
本例获取两个索引,一个是_id_,一个是content_text。
- 删除索引
删除其中的content_text
db.auction_sh_full_done_person_content_part_10000.dropIndex("content_text")
因为此时的索引为content_text
- 再次查找
删掉索引用时:0.539s
db.auction_sh_full_done_person_content_part_10000.find({"content":/张乙娥/})
如果使用Python 通过pymongo来索引:
from pymongo import MongoClient
#uri = "mongodb://localhost:27017/"
#client_mongodb = MongoClient(uri)
host,port = "localhost",27017
mongo =MongoClient(host,port)
collection=mongo['shanghai_sf']['auction_sh_full_done_person_content']
ans=collection.find_one({"$text":{"$search":"张乙娥"}})
print(ans)
得到结果:
{'_id': ObjectId('5b7c2b05d129bb283b19ceba'), 'content': "(2016)粤0604民初3505号 原告:张乙娥,女……}
目前建立索引还是放在客户端,只是用pymongo来检索一些信息
参考资料:http://www.runoob.com/mongodb/mongodb-text-search.html
后面再捣鼓捣鼓Elasticsearch弹性搜索吧……比较一下。