MongoDB查找语法

MongoDB的查找最重要的函数是find

find()函数第一个参数是查找文档,第二个参数可以限制返回的键

查询条件

'$lt' $lte $gt $gte 使用 分别代表< 、<=、>、>=

$ne 表示不相等

我的docs 是这样组织的

        doc ={
            'title':title,
            'description':desc,
            'classname':classname,
            'pdflocation':pdf_path,
            'sourcelocation':source_path,
            'uploadtime':time.strftime('%F %X',time.localtime(time.time())),
            'downloadcount':0,
            'username':username,
            'cover':"",
           'recentDownload':[],
        }

查找某一个条件可以这样写

#连接数据库操作 语言为python  
from pymongo import Connection

#连接到test数据库,MongoDB默认自带的测试数据库
db = Connection("localhost", 27017).test

db.docs.find({'title':'hehe'})

当然我也可以限制只返回pdflocation

db.docs.find({'title':'hehe'},{'pdflocation':1})

或者除了pdflocation都要

db.docs.find({'title':'hehe'},{'pdflocation':0})

上面的操作返回docs数据集中title 为hehe的文档

如果我想找到时间在某一个范围内的doc,我可以这样写

docs = db.docs.find({'uploadtime':{
        '$lte':time.strftime('%F %X',time.localtime(time.time())),
        '$gt':time.strftime('%F %X',time.localtime(time.time())),
        }
    })

当然既小于当前时间又大于当前时间的doc肯定不错在了,所以返回None

像上面的查询文档中的关系类似 sql中的where A and B

那么要查找where a or b 该怎么办?

或关系查找

使用 $in 或者 $or

比如我想查找文档中名字是 test1 或 test2的 可以这样

docs = db.docs.find({'title':{
        '$in':['test1','test2'],
        }
    })

对于某个键的或查找,这样效率是很不错的

相对应的还有nin not in 不在这个里面的 很容易理解

那么要找题目(title)或者描述(description)是test的怎么查找呢?

$or

需要注意的是$or后面需要的是一个list ,list每一项就是一个或的一个条件

docs = db.docs.find({
    '$or':[{'title':'test'},{'description':'test'}]
    })

逻辑操作

有了$or当然也由其他逻辑操作符号
$not 取反 与正则表达式一起使用将极为高效
$and 很少使用 默认在一个{}中的条件都是and关系

这几个使用基本相同 后面都需要接一个数组
数组的每一项都是字典,里面是进行逻辑组合的条件

模糊搜索

使用要使用像Sql中 where A like "%s% " 可以使用正则表达式来匹配

Mongodb支持于Perl兼容的正则表达式来匹配字符串

在python的pymongo这个库中可以这样写

利用re模块

docs = db.docs.find({'title':re.compile('[\w]+')})

或者利用$regex

docs = db.docs.find({'title':{'$regex':'[\w]+'}})

这样就支持了我在py中用的正则表达式了

键的值非空

传统Sql数据中一般都由Null字段

MongoDB也是有的,在python中对应的是None

查找名字非空的文档

docs = db.docs.find({'title':{'$ne':None}})

查找名字为空的文档

docs = db.docs.find({'title':{'$in':[None]}})

查询数组

MongoDB中某个键的值是list是是经常使用的,比如doc

recentDownload 字段是一个list,每次有人下载该文档,
都将下载者的di放到这个list 中(很不推荐这样做,这只是个例子

比如 coco、joe、tom最近下载了这个文档

那么

docs = db.docs.find({'recentDownload':'coco'})
docs = db.docs.find({'recentDownload':'joe'})

都将返回这个文档

那么如果想找到coco和tom最近下载了哪个文档

需要用$all

docs = db.docs.find({'recentDownload':{'$all':['coco','tom']}})

并且all后面的数组的顺序不影响结果

当然你也可以精确匹配

docs = db.docs.find('recentDownload':['coco','joe'])

这里的['coco','joe']是一个元素 除非recentDownload完全等于这个list,否则不会匹配

如果知道顺序也可以这样查找
查找recentDownload2的第二个元素是coco

docs = db.docs.find('recentDownload.2':'coco')

使用$size可以查找到特定长度的数组

文档被下载的次数越来越多,这个list也越来大,如果只想知道最近哪十个人下载了这个文档

可以在更新指定这个list的大小,也可以在查询时用$slice来限制返回的数量

从前到后的10个

docs = db.docs.find({'recentDownload':{'$slice':10}})

我们想要最近下载的十个人的id 那么
但是在python中报错了

pymongo.errors.OperationFailure: database error: Can't canonicalize query: BadValue unknown operator: $slice

怀疑pymongo不支持

docs = db.docs.find({'recentDownload':{'$slice':-10}})

就可以了

查询数组与范围查询的相互影响

我们现在由这样的文档

{'x': 5 }
{'x': 15 }
{'x': 25 }
{'x': [5,25 }

执行这样的查询

docs = db.testDoc.find({'x':{'$gt':6,'$lt':24}})

发现输出

{u'x': 15, u'_id': ObjectId('54815f29348e3b14df008c41')}
{u'x': [5, 25], u'_id': ObjectId('54815f29348e3b14df008c43')}

不应该啊! 5 和25 都不在这个范围啊!

原因在于:
5满足小于24 6满足大于5的条件,故这个文档被返回了

这时候需要使用$elemMatch操作符

这时候返回空

..因为$elemMatch只搜索数组

解决这个问题的方法需要使用“索引”

查询内联文档

一个键的值出了可以是一个list之外,当然可以是一个文档(dict)了
比如文档作者可以由名字和性别组成

 {'author':{
    'name':'coco',
    'sex':'f'
}}

那么可以这样搜索
查询author的名字为coco的文档

docs = db.testDoc.find({'author.name':'coco'})

但是如果这个coco有男有女怎么办呢?
和list时一样一个dict要满足所有条件需要使用$elemMatch

注 这里发生了些许问题,问题的原因不明,正在寻找问题的原因

docs = db.testDoc.find({'author':{'$elemMatch':{'name':'coco','sex':'f'}}})

如果使用javascript 还可以在$where语句之后添加函数 ,相当牛X

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容