0

我正在尝试使用一种构建器模式来构建使用多个条件的 OR 查询,具体取决于场景。一个例子是

    public class Stylist extends Model {

      public String firstName;

      public String lastName;

      public String status;

      ...

      }

如果名字或姓氏与给定字符串匹配并且状态与另一个字符串匹配,我想搜索 Stylist 集合。我正在编写如下查询:

      MorphiaQuery query = Stylist.q();
      if (some condition) {
      query.or(query.criteria("status").equal("PendingApproval"), query.criteria("status").equal(EntityStatus.ACTIVE));    
      }

      if (some other condition as well) {
      query.or(query.criteria("firstName").containsIgnoreCase(name), query.criteria("lastName").containsIgnoreCase(name));
      }

当这两个条件都满足时,我看到该查询仅包含与名字和姓氏相关的条件,即不添加/附加不同的 OR 条件而是覆盖。它与附加所有不同过滤条件的过滤条件完全不同,您可以轻松构建包含多个 AND 条件的查询。

我可以通过以不同的方式放置条件并以不同的方式构建查询来解决问题,但这似乎不是一种优雅的方式。难道我做错了什么 ?

我正在使用播放!框架 1.2.4 和 Play Morphia 模块版本 1.2.5a

更新

更清楚地说,我想 AND 多个 OR 查询。具体来说,在上述情况下,我想

我想在哪里搜索造型师:

firstName or lastName contains supplied name AND

status equals ACTIVE or PENDING_APPROVAL.

我已经能够通过以下方式直接在 Mongo shell 上构建查询:

db.stylists.find({$and: [{$or : [{status: "PENDING_APPROVAL"}, {status : "ACTIVE"}]},{$or : [{firstName : { "$regex" : "test " , "$options" : "i"}}, {lastName : { "$regex" : "test" , "$options" : "i"}}]}] }).pretty();

但无法通过 Query API 方法实现相同的目的。这是我的尝试:

    Query<Stylist> query = MorphiaPlugin.ds().find(Stylist.class);

    CriteriaContainer or3 = query.or(query.criteria("firstName").containsIgnoreCase(name), query.criteria("lastName").containsIgnoreCase(name));

    CriteriaContainer or4 = query.or(query.criteria("status").equal("PENDING_APPROVAL"), query.criteria("status").equal("ACTIVE"));

    query.and(or3, or4);

query.toString() 产生以下输出: { "$or" : [ { "status" : "PENDING_APPROVAL"} , { "status" : "ACTIVE"}]}

不确定,我在哪里失踪?

4

1 回答 1

1

我想可能有两种方法可以处理您的案件:

首先,使用List<Criteria>

MorphiaQuery query = Stylist.q();
List<Criteria> l = new ArrayList<Criteria>()

if (some condition) {
  l.add(query.criteria("status").equals("PendingApproval");
  l.add(query.criteria("status").equal(EntityStatus.ACTIVE));
}

if (some other conditional as well) {
  l.add(query.criteria("firstName").containsIgnoreCase(name));
  l.add(query.criteria("lastName").containsIgnoreCase(name));
}

query.or(l.toArray());

二、使用CritieriaContainer

MorphiaQuery query = Stylist.q();
CriteriaContainer cc = null;

if (some condition) {
  cc = query.or(query.criteria("status").equal("PendingApproval"), query.criteria("status").equal(EntityStatus.ACTIVE));
}

if (some other condition) {
  if (null != cc) query.or(cc, query.criteria("firstName").containsIgnoreCase(name), query.criteria("lastName").containsIgnoreCase(name));
  else query.or(query.criteria("firstName").containsIgnoreCase(name), query.criteria("lastName").containsIgnoreCase(name));
}
于 2012-10-01T11:00:37.730 回答