Parse的文档解释了如何使用OR运算符添加多个约束,使用此示例。
ParseQuery<ParseObject> lotsOfWins = ParseQuery.getQuery("Player");
lotsOfWins.whereGreaterThan(150);
ParseQuery<ParseObject> fewWins = ParseQuery.getQuery("Player");
fewWins.whereLessThan(5);
List<ParseQuery<ParseObject>> queries = new ArrayList<ParseQuery<ParseObject>>();
queries.add(lotsOfWins);
queries.add(fewWins);
ParseQuery<ParseObject> mainQuery = ParseQuery.or(queries);
mainQuery.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> results, ParseException e) {
// results has the list of players that win a lot or haven't won much.
}
});
但我想在Conjunctive normal form中添加多个OR运算符。得到这样的东西:(a OR b OR c)AND(d OR e OR f)AND(g OR h OR i)
有什么方法可以做到这一点吗?
答案 0 :(得分:0)
它肯定不是sql,但是在同一查询中支持AND作为复合条件,并且使用Query.or方法支持OR。换句话说,冒着过于笼统的风险,将你的逻辑转换为析取形式:
(a OR b) AND (c OR d) = (a AND c) OR (b AND c) OR (a AND d) OR (b AND d)
并为每个析取操作数构建查询,每个操作数都应用了多个连接操作数。
编辑 - 关于一个非常大的析取,我在文档中找不到OR允许的查询操作数的限制,但是有意义的是存在限制并且解析会使它变小。
当您用尽query.or限制时,可以通过串行运行批处理并对结果求和来实现析取。换句话说,将查询分组为10或其他,使用OR连续运行它们,每次将结果添加到排除重复项的累积集中。
但无论你如何对其进行分割,非常复杂的条件都会导致计算开销,这些开销会在某些时候遇到资源限制(一些人为基于你正在使用的薪酬等级)。
例如,假设您从上面的谓词开始,并且您已将其转换为析取形式,就像我一样。比如说,Query.or仅限于2个查询。您仍然可以按顺序执行两个或两个,并将结果汇总(如js):
var queryAC = new Parse.Query("MyClass");
// set queryAC.whereEqualTo(), where... for constraint a
// set queryAC.whereEqualTo(), where... for constraint c
var queryBC = new Parse.Query("MyClass");
// set queryAC.whereEqualTo(), where... for constraint b
// set queryAC.whereEqualTo(), where... for constraint c
var queryAD = new Parse.Query("MyClass");
// set queryAC.whereEqualTo(), where... for constraint a
// set queryAC.whereEqualTo(), where... for constraint d
var queryBD = new Parse.Query("MyClass");
// set queryAC.whereEqualTo(), where... for constraint b
// set queryAC.whereEqualTo(), where... for constraint d
// now, run them as or, serially. in JS using promises...
var cumulativeResults = [];
Parse.Query.or(queryAC, queryBC).then(function(results) {
cumulativeResults = cumulativeResults.concat(results);
return Parse.Query.or(queryAD, queryBD);
// this is how to do it in js with promises, in Java, the
// equivalent idea is to run the next or in the completion
// callback of the first one
}).then(function (results) {
cumulativeResults = cumulativeResults.concat(results);
// remove dups here based on objectId, or do it in the line
// above when adding results.
// now cumulativeResults contains the OR sum of the original expression
});
关于应用deMorgan的规则,解析通过提供否定对应物来象征性地处理否定词,例如: whereEqualTo
可以否定whereNotEqualTo
。我很确定这些都不是功能完整的...我偶尔会遇到无法表达我需要的情况。我在这一点上的方法是尽可能少地读入内存并使用app逻辑从那里应用逻辑测试。