仿照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上查询线上数据库数据,今天也是平常的一次操作 集合 ...
随机推荐
- nodejs异步转同步
项目在微信环境开发,需要获取access_token进行授权登录和获取用户信息. 特意把这块功能拿出来封装一个自定义module module.exports = new Wechat(con.app ...
- python中的zip()函数和map()函数
一.zip()函数 1.语法: zip(iterable, ...) 参数说明: iterable,...-- 一个或多个迭代器; 在python2中: zip() 函数用于将可迭代的对象作为参数,将 ...
- 时空地图TimeGIS.com生成正交曲线网格
数值模拟中对数学物理方程的求解过程中经常需要生成网格,这里提供了一种方便的方法,只需要简单地勾画出区域的轮廓, 就可以生成相应的正交曲线网格,详情请访问 www.TimeGIS.com
- arcgis api 4.x for js之基础地图篇
arcgis api3.x for js转向arcgis api4.x,我也是最近的3-4个月时间的事情,刚好公司有个webgis项目需要展示三维场景,项目选择arcgis api4.x.我纯碎记录一 ...
- Python数据处理与计算——概述
Python是一种面向对象的,动态的程序设计语言,具有非常简洁而清晰的语法,适合于完成各种高层任务.它既可以用来快速开发程序脚本,也可以用来开发大规模的软件. 随着NumPy.SciPy.Matplo ...
- 微信分享大图遇到的问题(Android)
起因: 要做一个微信图片分享的功能,但是对于大图会如下问题: 当时没有仔细查看错误日志,单纯的以为是图片太大的问题. 分享图片代码: public void WXsharePic(String tra ...
- Flutter项目之app升级方案
题接上篇的文章的项目,还是那个空货管理app.本篇文章用于讲解基于Flutter的app项目的升级方案. 在我接触Flutter之前,做过一个比较失败的基于DCloud的HTML5+技术的app,做过 ...
- Python笔记-高阶函数
1.函数式编程 函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量. 函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数! 传入函数 既然 ...
- java集合介绍(List,Set,Map)
前言 介绍java的常用集合+各个集合使用用例 欢迎转载,请注明作者和出处哦☺ 参考: 1,<Java核心编程技术(第二版)> 2, http://www.cnblogs.com/Litt ...
- 手把手教新手小白在window把自己的项目上传到github
作为一个开发者,写博客,上传项目到github好像是不可不会的技能,很多有经验的老司机都会这么建议你.本宝宝第一次要把项目传到github的时候,确实有点蒙蔽,什么鬼,传个东西有必要这么难吗? git ...