仿照selalchemy实现简单的mongo查询
首先这是一个很奇葩的需求,时间紧迫顺手胡写了一个,以后看看有没有好的思路
def and_(item_list):
return "%s:[%s]" % ("$and", ','.join(loop_func(item_list))) def or_(item_list):
return "%s:[%s]" % ("$or", ','.join(loop_func(item_list))) def lt(a, b):
return "%s<%s" % (a.name, b) def le(a, b):
return "%s<=%s" % (a.name, b) def ne(a, b):
return "%s!=%s" % (a.name, b) def ge(a, b):
return "%s>=%s" % (a.name, b) def eq(a, b):
return "%s=%s" % (a.name, b) def gt(a, b):
return "%s>%s" % (a.name, b) def in_op(a, b):
return '%s:{$in:%s}' % (a.name, b) def notin_op(a, b):
return '%s:{$nin:%s}' % (a.name, b) def desc_op(a):
return a def asc_op(a):
return a.asc() class ColumnOperators(object):
__slots__ = ['name'] def __init__(self, name):
self.name = name def __and__(self, other):
return self.operate(and_, other) def __or__(self, other):
return self.operate(or_, other) def __lt__(self, other):
return self.operate(lt, other) def __le__(self, other):
return self.operate(le, other) def __eq__(self, other):
return self.operate(eq, other) def __ne__(self, other):
return self.operate(ne, other) def __gt__(self, other):
return self.operate(gt, other) def __ge__(self, other):
return self.operate(ge, other) def operate(self, op, other):
return op(self, other) def in_(self, other):
return self.operate(in_op, other) def notin_(self, other):
return self.operate(notin_op, other) def desc(self):
return '{%s:1}' % self.name def asc(self):
return '{%s:-1}' % self.name dic = {'<': '$lt', '<=': '$lte', '=': '$eq', '>=': '$gte', '>': '$gt', '!=': '$ne'} def split_func(item, op):
split_item_list = item.strip().split(op) if len(split_item_list) != 2:
raise NotImplementedError("不支持同时两个及以上比较运算")
for split_item in split_item_list:
for key in dic:
if key in split_item:
raise NotImplementedError("不支持同时两个及以上比较运算")
return split_item_list, op def loop_func(item_list):
and_or_list = []
for item in item_list:
if ">=" in item:
split_item_list, op = split_func(item, ">=")
and_or_list.append("{%s:{%s:%s}}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip()))
elif "<=" in item:
split_item_list, op = split_func(item, "<=")
and_or_list.append("{%s:{%s:%s}}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip()))
elif "!=" in item:
split_item_list, op = split_func(item, ">=")
and_or_list.append("{%s:{%s:%s}}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip()))
elif "<" in item:
split_item_list, op = split_func(item, "<")
and_or_list.append("{%s:{%s:%s}}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip()))
elif "=" in item:
split_item_list, op = split_func(item, "=")
and_or_list.append("{%s:{%s:%s}}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip()))
elif ">" in item:
split_item_list, op = split_func(item, ">")
and_or_list.append("{%s:{%s:%s}}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip()))
else:
and_or_list.append('{%s}' % item)
return and_or_list def handle_op(item):
if ">=" in item:
split_item_list, op = split_func(item, ">=")
return "%s:{%s:%s}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip())
elif "<=" in item:
split_item_list, op = split_func(item, "<=")
return "%s:{%s:%s}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip())
elif "!=" in item:
split_item_list, op = split_func(item, "!=")
return "%s:{%s:%s}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip())
elif "<" in item:
split_item_list, op = split_func(item, "<")
return "%s:{%s:%s}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip())
elif "=" in item:
split_item_list, op = split_func(item, "=")
return "%s:{%s:%s}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip())
elif ">" in item:
split_item_list, op = split_func(item, ">")
return "%s:{%s:%s}" % (split_item_list[0].strip(), dic[op], split_item_list[1].strip())
else:
return item class Query(object):
__slots__ = ['_projection_list', '_query_criteria_list', '_exec_order'] def __init__(self, *entities):
self._projection_list = []
self._query_criteria_list = []
self._set_entities(*entities)
self._exec_order = [] def _set_entities(self, *entities):
if entities is not ():
for ent in list(entities):
self._projection_list.append(ent.name) def filter(self, *criterion):
if criterion is not ():
for cri in list(criterion):
self._query_criteria_list.append(handle_op(cri))
return self def order_by(self, standard):
if 'sort' not in self._exec_order:
self._exec_order.append({'sort': standard})
else:
raise RuntimeError("sort方法只能调用一次")
return self def limit(self, num):
if 'limit' not in self._exec_order:
self._exec_order.append({'limit': num})
else:
raise RuntimeError("limit方法只能调用一次")
return self def skip(self, num):
if 'skip' not in self._exec_order:
self._exec_order.append({'skip': num})
else:
raise RuntimeError("skip方法只能调用一次")
return self def query(*args):
return Query(*args) class Users(object):
id = ColumnOperators('id')
name = ColumnOperators('name')
age = ColumnOperators('age') def conditions(self): # 可以将这个方法写到类中,考虑到尽可能少的暴漏接口,就另外写了
dic = {}
if self._projection_list:
dic["columnStr"] = "{%s}" % (",".join(self._projection_list))
if self._query_criteria_list:
if len(self._query_criteria_list) == 1:
dic["condition"] = "{%s}" % (",".join(self._query_criteria_list))
else:
dic["condition"] = "{$and:[%s]}" % (",".join(['{%s}' % con for con in self._query_criteria_list]))
for i in self._exec_order:
dic.update(i)
return dic if __name__ == '__main__':
Query.conditions = property(conditions)
query_obj = query(
Users.id,
Users.name
).filter(
and_([Users.id > 5, Users.age > 20]),
or_([Users.name == 'Tom', Users.name == 'Jade'])
).order_by(Users.age.desc()).limit(3)
print(query_obj.conditions)
仿照selalchemy实现简单的mongo查询的更多相关文章
- 整理最近用的Mongo查询语句
背景 最近做了几个规则逻辑.用到mongo查询比较多,就是查询交易信息跑既定规则筛选出交易商户,使用聚合管道进行统计和取出简单处理后的数据,用SQL代替业务代码逻辑的判断. 方法 MongoDB聚合使 ...
- 我的EntityFramework(2):简单的数据查询
原文:我的EntityFramework(2):简单的数据查询 在上一篇博文中,已经搭建了基本的框架,接下来就进行简单的数据查询,这里主要用了Linq 常见的数据集查询 var companyList ...
- MyBatis简单的增删改查以及简单的分页查询实现
MyBatis简单的增删改查以及简单的分页查询实现 <? xml version="1.0" encoding="UTF-8"? > <!DO ...
- C++ 容器的综合应用的一个简单实例——文本查询程序
C++ 容器的综合应用的一个简单实例——文本查询程序 [0. 需求] 最近在粗略学习<C++ Primer 4th>的容器内容,关联容器的章节末尾有个很不错的实例.通过实现一个简单的文本查 ...
- 发送json-简单的传参查询和简单的sql查询
简单的传参查询并转化为json using System; using System.Collections.Generic; using System.Linq; using System.Web; ...
- Mongo 查询
Mongo 查询 mongo js 遍历 db.getCollection('CPU').find({}).limit(100).sort({"time":-1}).forEa ...
- SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法
软件152 尹以操 首先谢谢大佬的简书文章:http://www.jianshu.com/p/45ad65690e33# 这篇文章中讲的是spring中使用spring data jpa,使用了xml ...
- Mongo查询百万级数据性能问题及JAVA优化问题
Mongo查询百万级数据 使用分页 skip和limit 效率会相当慢 那么怎么解决呢 上代码 全部查询数据也会特别慢 Criteria criteria = new Criteria(); ...
- 一次mongo查询不存在字段引发的事故
话说今天的一个小小的查询失误给了我比较深刻的教训,也让我对mongo有了更深刻的理解,下面我们来说说这个事情的原委: 我们经常使用阿里云子账号在DMS上查询线上数据库数据,今天也是平常的一次操作 集合 ...
随机推荐
- shiro缓存管理
一. 概述 Shiro作为一个开源的权限框架,其组件化的设计思想使得开发者可以根据具体业务场景灵活地实现权限管理方案,权限粒度的控制非常方便.首先,我们来看看Shiro框架的架构图:从上图我们可以很清 ...
- PhotoshopCS5中将单位修改成百分比
PhotoshopCS5中单位默认是厘米或px,当用同一动作修改两张照片时,会因为片子大小不同,修改收到影响.若将单位修改成百分比,则动作会根据照片大小,自动进行调整. 1)选择菜单栏中的“编辑”选项 ...
- Django 项目中添加静态文件夹
在 mysite 文件夹下添加一个 statics 文件夹用来存放 js 文件 在 index.html 文件中添加 <!DOCTYPE html> <html lang=" ...
- Android 设计模式之MVC模式
说到Android设计模式的MVC模式,估计很多人都是比较熟悉了,这里深入了解一下MVC到底是怎么回事,以ListView为例子讲解. 一.深入理解MVC概念 MVC即Model-View-Contr ...
- C#格式化
格式化表示的一般格式 { N [ , M ] [ :格式码 ] } N: 指定参数序列中的输出序号,比如{0} , {1}, {2}等. M: 指定参数输出的最小长度. 如果参数长度小于M,则空格填 ...
- windows docker redis
拉取docker docker pull hub.c.163.com/library/redis:latest 启动docker docker run -p 6379:6379 -d hub.c.16 ...
- 《单元测试之道Java版》的读书笔记
总览 第2章 首个单元测试 第3章 使用JUnit编写测试 3.1 构建单元测试 3.2 JUnit的各种断言 3.3 JUnit框架 4. 测试什么? 5.CORRECT(正确的)边界条件 6.使用 ...
- Python爬虫【实战篇】scrapy 框架爬取某招聘网存入mongodb
创建项目 scrapy startproject zhaoping 创建爬虫 cd zhaoping scrapy genspider hr zhaopingwang.com 目录结构 items.p ...
- IBM developer:Kafka ACLs
Overview In Apache Kafka, the security feature is supported from version 0.9. When Kerberos is enabl ...
- Neutron:浮动ip
如果需要从外网直接访问 instance,则可以利用 floating IP. 下面是关于 floating IP 必须知道的事实: 1. floating IP 提供静态 NAT 功能,建立外网 ...