0

シナリオに応じて複数の基準を使用して、一種のビルダー パターンを使用して OR クエリを作成しようとしています。例は

    public class Stylist extends Model {

      public String firstName;

      public String lastName;

      public String status;

      ...

      }

名または姓が特定の文字列と一致し、ステータスが別の文字列と一致する場合、スタイリスト コレクションを検索したいと思います。私は次のようにクエリを書いています:

      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));
      }

両方の条件が満たされると、クエリには firstName と lastName に関連する基準のみが含まれていることがわかります。つまり、異なる OR 基準は追加/追加されずに上書きされます。これは、さまざまなフィルター条件がすべて追加されるフィルター条件とはまったく異なり、複数の AND 条件を含むクエリを簡単に作成できます。

条件を変更し、クエリを別の方法で作成することで問題を解決できますが、エレガントな方法ではないようです。私は何か間違っていますか?

私はプレイを使用しています!Framework 1.2.4 および Play Morphia モジュール バージョン 1.2.5a

アップデート

より明確に言えば、複数の OR クエリに AND を適用したいと考えています。具体的には、上記のシナリオで、

スタイリストを検索したい :

firstName or lastName contains supplied name AND

status equals ACTIVE or PENDING_APPROVAL.

次の方法で、Mongo シェルで直接クエリを作成できました。

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

しかし、クエリ 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

あなたのケースを処理するには2つの方法があると思います:

まず、使用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 に答える