首先这是一个很奇葩的需求,时间紧迫顺手胡写了一个,以后看看有没有好的思路

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查询的更多相关文章

  1. 整理最近用的Mongo查询语句

    背景 最近做了几个规则逻辑.用到mongo查询比较多,就是查询交易信息跑既定规则筛选出交易商户,使用聚合管道进行统计和取出简单处理后的数据,用SQL代替业务代码逻辑的判断. 方法 MongoDB聚合使 ...

  2. 我的EntityFramework(2):简单的数据查询

    原文:我的EntityFramework(2):简单的数据查询 在上一篇博文中,已经搭建了基本的框架,接下来就进行简单的数据查询,这里主要用了Linq 常见的数据集查询 var companyList ...

  3. MyBatis简单的增删改查以及简单的分页查询实现

    MyBatis简单的增删改查以及简单的分页查询实现 <? xml version="1.0" encoding="UTF-8"? > <!DO ...

  4. C++ 容器的综合应用的一个简单实例——文本查询程序

    C++ 容器的综合应用的一个简单实例——文本查询程序 [0. 需求] 最近在粗略学习<C++ Primer 4th>的容器内容,关联容器的章节末尾有个很不错的实例.通过实现一个简单的文本查 ...

  5. 发送json-简单的传参查询和简单的sql查询

    简单的传参查询并转化为json using System; using System.Collections.Generic; using System.Linq; using System.Web; ...

  6. Mongo 查询

    Mongo 查询   mongo js 遍历 db.getCollection('CPU').find({}).limit(100).sort({"time":-1}).forEa ...

  7. SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法

    软件152 尹以操 首先谢谢大佬的简书文章:http://www.jianshu.com/p/45ad65690e33# 这篇文章中讲的是spring中使用spring data jpa,使用了xml ...

  8. Mongo查询百万级数据性能问题及JAVA优化问题

    Mongo查询百万级数据  使用分页  skip和limit 效率会相当慢   那么怎么解决呢  上代码 全部查询数据也会特别慢 Criteria criteria = new Criteria(); ...

  9. 一次mongo查询不存在字段引发的事故

    话说今天的一个小小的查询失误给了我比较深刻的教训,也让我对mongo有了更深刻的理解,下面我们来说说这个事情的原委: 我们经常使用阿里云子账号在DMS上查询线上数据库数据,今天也是平常的一次操作 集合 ...

随机推荐

  1. [TCP/IP] 数据链路层-ethereal 抓包分析数据帧

    1.下载 http://dx1.pc0359.cn/soft/e/ethereal.rar 2.打开软件,指定抓取的网卡,下面是我抓取自己的主要网卡数据 3.开启个ping命令 , 不停的ping一台 ...

  2. Java虚拟机垃圾收集算法

    1.标记-清除算法 标记-清除算法分为 "标记" 和 "清除" 两个步骤:首先标记出所有需要回收的对象,然后在标记完成后统一回收所有被标记的对象,是垃圾收集算法 ...

  3. Java 适配器(Adapter)模式

    一.什么是适配器模式: 把一个接口变成另外一个接口,使得原本因接口不匹配无法一起工作的两个类一起工作. 二.适配器模式的分类和结构: 适配器模式有类的适配器模式和对象的适配器模式两种. 1.类的适配器 ...

  4. Django 创建一个返回当前时间的页面

    创建一个 Django 项目及应用 django-admin startproject mysite cd mysite # 手动创建一个 templates 文件夹用来保存 html 文件 mkdi ...

  5. WEB前端学习资源清单

    常用学习资源 JS参考与基础学习系列 [MDN]JS标准参考 es6教程 JS标准参考教程 编程类中文书籍索引 深入理解JS系列 前端开发仓库 <JavaScript 闯关记> JavaS ...

  6. 5分钟入门LingaScript-尝鲜中文版TypeScript

    续前文转载: 中文輸進去,程式出得來,開發者發大財 -LingaScript:中文化TypeScript, 虽然其中例程使用了繁体中文语法, 但它同时也支持简体中文语法. 注: 此文中VS Code的 ...

  7. jquery 同步加载

    jquery在前端展示时,如果需要从服务器获取信息然后在更新,需要设置同步加载. async属性设置为:false即可. $.ajax({ url : 'test.php', type : 'post ...

  8. WIn10系统软件默认安装c盘后消失看不见问题

    一.win10系统下c盘,program 文件下 软件一般为32 或者 64位,但是现在win10系统有些C盘会显示program  x86 向这种情况的话我们的软件默认安装在这个盘的话可能会造成很多 ...

  9. vue源码分析—认识 Flow

    认识 Flow Flow 是 facebook 出品的 JavaScript 静态类型检查⼯具.Vue.js 的源码利⽤了 Flow 做了静态类型检查, 所以了解 Flow 有助于我们阅读源码 Flo ...

  10. 从Python越来越想放弃的Day09

    今天在学几个新东东,又向py迈了一大步,依旧是从简单的开始,三元运算,又称三目运算,所谓三目,也就是二郎神,跑题了,简单的格式为v = 前面 if 条件 else 后面,条件为True时,则v = 前 ...