是否有任何最佳实践或ReQL功能有助于编写复杂的ReQL查询?
为了说明这一点,想象一下fruits
表。每个文档都有以下结构。
{
"id": 123,
"name": "name",
"colour": "colour",
"weight": 5
}
如果我们想要检索所有绿色水果,我们可能会使用以下查询。
r
.db('db')
.table('fruits')
.filter({colour: 'green'})
但是,在更复杂的情况下,我们可能希望使用各种复杂的命令组合。在这种情况下,可以针对每个案例编写定制查询,但这可能难以维护并且可能违反不要重复自己(DRY)原则。相反,我们可能希望编写可以链接自定义命令的定制查询,从而允许以模块化方式组合复杂查询。这可能采取以下形式。
r
.db('db')
.table('fruits')
.custom(component)
component
可以是一个函数,它接受命令链中的最后一个实体作为其参数并返回一些内容,如下所示。
function component(chain)
{
return chain
.filter({colour: 'green'});
};
这不是一个功能提案,而是一个复杂查询问题的例证,尽管这样的功能看似直观有用。
就个人而言,我自己解决这个问题的努力涉及创建compose
效用函数。它以一系列函数作为主要参数。调用每个函数,传递查询链的一部分,并期望返回查询链的修订版本。迭代完成后,将返回composition
个查询组件。这可以在下面看到。
function compose(queries, parameters)
{
if (queries.length > 1)
{
let composition = queries[0](parameters);
for (let index = 1; index < queries.length; index++)
{
let query = queries[index];
composition = query(composition, parameters);
};
return composition;
}
else
{
throw 'Must be two or more queries.';
};
};
function startQuery()
{
return RethinkDB;
};
function filterQuery1(query)
{
return query.filter({name: 'Grape'});
};
function filterQuery2(query)
{
return query.filter({colour: 'Green'});
};
function filterQuery3(query)
{
return query.orderBy(RethinkDB.desc('created'));
};
let composition = compose([startQuery, filterQuery1, filterQuery2, filterQuery3]);
composition.run(connection);
很高兴知道这样的事情是否存在,是否有处理此类案例的最佳实践,或者这是否是ReQL可以从改进中受益的领域。
答案 0 :(得分:0)
在RethinkDB文档中,他们清楚地说明了这一点:所有ReQL查询都是可链接的
通过在编程中进行函数调用来构造查询 你已经知道的语言。您不必连接字符串或 构造专门的JSON对象来查询数据库。 所有ReQL 查询是可链接的。您从表开始并逐步链接 变换器使用的查询结束。操作
你不必撰写另一个只隐含你的代码的东西,这会使它更难以阅读并最终变得不必要。
简单的方法是将rethinkdb查询和过滤器分配到变量中,只要您需要添加更复杂的逻辑,直接添加到这些变量,然后在查询完成时运行()它
假设我必须搜索具有不同过滤器输入并获得分页的产品列表。以下代码在javascript中公开(这是仅用于说明的简单代码)
let sorterDirection = 'asc';
let sorterColumnName = 'created_date';
var buildFilter = r.row('app_id').eq(appId).and(r.row('status').eq('public'))
// if there is no condition to start up, you could use r.expr(true)
// append every filter into the buildFilter var if they are positive
if (escapedKeyword != "") {
buildFilter = buildFilter.and(r.row('name').default('').downcase().match(escapedKeyword))
}
// you may have different filter to add, do the same to append them into buildFilter.
// start to make query
let query = r.table('yourTableName').filter(buildFilter);
query.orderBy(r[sorterDirection](sorterColumnName))
.slice(pageIndex * pageSize, (pageIndex * pageSize) + pageSize).run();
&#13;