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

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. Java 适配器(Adapter)模式

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

  2. String-StringBuffer-StringBuilder的区别和源码分析

    一,String,StringBuffer,StringBuilder三者之间的关系 三个类的关系:StringBuffer和StringBuilder都继承自AbstractStringBuilde ...

  3. vue-router 用户登陆

    有些路由页面需要用户登陆之后才能访问如(用户中心),如果用户没有登陆就访问这些页面的话就应该转换到登陆页面,登陆成功之后在进入该页面. 需要用到的知识点有:H5中的会话存储(sessionStorag ...

  4. Spring MVC(二)基于标注的MVC

    1.基于标注的Spring MVC 1.1 建立一个项目导入jar包(ioc aop mvc) 拷贝容器对应的配置文件到src下 在WEB-INF建立一个login.jsp 1.2 在web.xml ...

  5. 第二章 Linux目录学习

    Linux 目录结构相对windows来说更简单,Linux 目录 以 斜杠 / 为根目录,其整体结构是以/为根的树状结构. 使用 tree -L 1 查看1级目录结构 /bin 常用的二进制命令目录 ...

  6. 关于sass与VScode 一些配置 学习记录

    VScode三个关于sass的插件 .vscode-Sass------sass/scss文件语法提示.(sublime text也有) .vscode-Easy Sass------scss编译成c ...

  7. 为什么 User 应该翻译为 「使用权人」 ?

    User, 旧译「用户」,我在此向大家倡议有条件地选择翻译为「使用权人」. 1. __使用权人__更能反应 User 的本质特征 我们看到一匹马的时候不会说这是一头猪,而 User 的本质是什么?在我 ...

  8. 基于.net EF6 MVC5+WEB Api 的Web系统框架总结(1)-Web前端页面

    本 Web 系统框架基于C# EF6+MVC+WebApi的快速应用开发平台.本节主要介绍Web前端页面设计与实现.Web前端页面主要分为普通列表页面.树状导航列表页面.普通编辑页面.数据导入页面.向 ...

  9. 【Java】itext根据模板生成pdf(包括图片和表格)

    1.导入需要的jar包:itext-asian-5.2.0.jar itextpdf-5.5.11.jar. 2.新建word文档,创建模板,将文件另存为pdf,并用Adobe Acrobat DC打 ...

  10. C# 匿名对象(匿名类型)、var、动态类型 dynamic——实用之:过滤类属性、字段实用dynamic

    例子 返回一个LIst<oject>类型 而oject含有 30个字段 而我只需要两个字段.这里实用dynamic 和 linq. 上代码: 注意select new {} 为匿名类型,这 ...