如何在柴油中实现嵌套过滤器?
How to implement nested filters in diesel?
我对 Rust 和 Diesel 很陌生。我现在正在尝试为这样的查询实现 Diesel 过滤:
-- @param1 is duration in years
-- @param2 is duration in months
SELECT columns FROM a
WHERE
(...dynamic AND clauses)
AND (((a.min_unit = "Years") AND (a.min_duration <= @param1))
OR ((a.min_unit = "Months") AND (a.min_duration <= @param2)))
(...dynamic AND clauses)
在文档和网络上进行了一些搜索后,我仍然找不到如何执行此操作。
我最接近的猜测是:
let param1 = ...;
let param2 = ...;
let mut query = a::table.select(a::all_columns).into_boxed();
// dynamic clauses: query = query.filter(...) ...
query = query.filter(a::min_unit.eq(Some("Years")).and(a::min_duration.le(Some(param1))))
.or_filter(a::min_unit.eq(Some("Months")).and(a::min_duration.le(Some(param2))));
// dynamic clauses: query = query.filter(...) ...
let results = a::table.load<A>(&*conn);
有人知道吗?
谢谢!
您的代码实际上看起来是正确的(我没有 运行 它)。这里的文档指出了它是如何完成的:https://docs.diesel.rs/diesel/query_dsl/trait.QueryDsl.html#method.or_filter foo.filter(bar).or_filter(baz) is like foo.filter(bar.or(baz))
但第二个是 "nested"。所以,要得到
(id = 5 OR other = 6) AND foo=7
一个会做
.filter(id.eq(5).or(other.eq(6))).filter(foo.eq(7))
。
希望对您有所帮助!
嗯,这是我最近的尝试:
let min_months_predicate = a::min_unit.eq(Some("Months"))
.and(a::min_duration.le(Some(param1)));
let min_years_predicate = a::min_unit.eq(Some("Years"))
.and(a::min_duration.le(Some(param1)));
query = query.filter(min_months_predicate.or(min_years_predicate))
.filter(a::max_duration.ge(Some(param2)));
debug!("TEST QUERY: {:?}", debug_query(&query));
产生这个查询:
"SELECT \"a\".\"id\", \"a\".\"code\", .... WHERE (\"a\".\"min_unit\" = AND \"a\".\"min_duration\" <= OR \"a\".\"min_unit\" = AND \"a\".\"min_duration\" <= ) AND \"a\".\"max_duration\" >= "
当我对这个查询使用 sql EXPLAIN 时,我得到了这个子句:
Filter: ((max_duration >= 60) AND (((min_unit = 'Months'::text) AND (min_duration <= 3)) OR ((min_unit = 'Years'::text) AND (min_duration <= 5))))
这似乎是正确的。
我对 Rust 和 Diesel 很陌生。我现在正在尝试为这样的查询实现 Diesel 过滤:
-- @param1 is duration in years
-- @param2 is duration in months
SELECT columns FROM a
WHERE
(...dynamic AND clauses)
AND (((a.min_unit = "Years") AND (a.min_duration <= @param1))
OR ((a.min_unit = "Months") AND (a.min_duration <= @param2)))
(...dynamic AND clauses)
在文档和网络上进行了一些搜索后,我仍然找不到如何执行此操作。 我最接近的猜测是:
let param1 = ...;
let param2 = ...;
let mut query = a::table.select(a::all_columns).into_boxed();
// dynamic clauses: query = query.filter(...) ...
query = query.filter(a::min_unit.eq(Some("Years")).and(a::min_duration.le(Some(param1))))
.or_filter(a::min_unit.eq(Some("Months")).and(a::min_duration.le(Some(param2))));
// dynamic clauses: query = query.filter(...) ...
let results = a::table.load<A>(&*conn);
有人知道吗?
谢谢!
您的代码实际上看起来是正确的(我没有 运行 它)。这里的文档指出了它是如何完成的:https://docs.diesel.rs/diesel/query_dsl/trait.QueryDsl.html#method.or_filter foo.filter(bar).or_filter(baz) is like foo.filter(bar.or(baz))
但第二个是 "nested"。所以,要得到
(id = 5 OR other = 6) AND foo=7
一个会做
.filter(id.eq(5).or(other.eq(6))).filter(foo.eq(7))
。
希望对您有所帮助!
嗯,这是我最近的尝试:
let min_months_predicate = a::min_unit.eq(Some("Months"))
.and(a::min_duration.le(Some(param1)));
let min_years_predicate = a::min_unit.eq(Some("Years"))
.and(a::min_duration.le(Some(param1)));
query = query.filter(min_months_predicate.or(min_years_predicate))
.filter(a::max_duration.ge(Some(param2)));
debug!("TEST QUERY: {:?}", debug_query(&query));
产生这个查询:
"SELECT \"a\".\"id\", \"a\".\"code\", .... WHERE (\"a\".\"min_unit\" = AND \"a\".\"min_duration\" <= OR \"a\".\"min_unit\" = AND \"a\".\"min_duration\" <= ) AND \"a\".\"max_duration\" >= "
当我对这个查询使用 sql EXPLAIN 时,我得到了这个子句:
Filter: ((max_duration >= 60) AND (((min_unit = 'Months'::text) AND (min_duration <= 3)) OR ((min_unit = 'Years'::text) AND (min_duration <= 5))))
这似乎是正确的。