我正在设计一个通用通知订阅系统,用户可以在订阅时根据MongoDB查询或更一般的json查询指定复合规则。订阅数据存储在MongoDB集合中。例如,
{ "userId": 1, "rule": {"p1": "a"} }
{ "userId": 2, "rule": {"p1": "a", "p2": "b"} }
{ "userId": 3, "rule": {"p3": {$gt: 3} } }稍后,当以json对象的形式出现的事件(如下面的事件)到达时,我希望找到事件机器的所有用户规则:
{"p1": "a", "p3": 4}上面的事件应该与示例中userId 1和3指定的规则相匹配。事件对象不必存储在MongoDB中。
虽然我可能可以通过在应用层编写一个循环来满足这个要求。为了提高效率,我真的很想在db层实现它,最好允许分布式(分片)执行,这是由于体积和延迟的需求。
这能实现吗?任何帮助都是非常感谢的。事实上,只要支持动态事件模式,我对其他NOSQL开放,并且有一种指定复合规则的方法。
发布于 2016-08-01 18:01:54
您正在尝试实现的目标是不可能的,至少在MongoDB中是这样的。
如果您对查询引擎的工作方式进行了推理,您将意识到这不是一个简单的解决方案。
在高级条件下,引擎将从查询中生成一个条件对象,然后根据该集合中的每个文档进行求值,从而得到一个布尔值,该值确定文档是否属于结果集。在您的情况下,您想做相反的事情,您想要基于文档生成一个条件对象,然后将它应用到您给它的某个东西(例如一个对象)。
即使有可能,在DB上这样做的成本也太高,因为它需要为每个对象编译表达式函数并执行它,因此无法优化查询的执行。更合理的做法是在数据库之外这样做,在那里您可以已经创建了表达式函数。
发布于 2016-09-08 01:10:50
不能将“比较查询运算符”存储在mongo数据库中,但可以这样做:
{ "userId": 1, "rule": {"p1": "a"} }
{ "userId": 2, "rule": {"p1": "a", "p2": "b"} }
{ "userId": 3, "rule": {"p3": {"value": 3, "operator":"gt"} } }您可以以字符串形式存储值和运算符,并且可以进行如下查询:
db.test.find({"rule.p3.comparator":"gt", "rule.p3.value":{$lt:4}})注意,如果您的“运算符”是"gt",则必须在查询中使用$lt (相反的比较运算符)。
完整的示例如下所示:
db.test.find({$or:[{"rule.p3.comparator":"gt", "rule.p3.value":{$lt:4}}, {"rule.p1":"a"}]})此查询与所需的userId 1和3匹配。
https://stackoverflow.com/questions/38690045
复制相似问题