Rally Web サービス APIの紹介ページには、複雑なクエリを記述する際の落とし穴についての説明がいくつかあります (クエリの構文とオブジェクト コレクションの属性とクエリのセクションを参照してください)。Java 版はチェーン式を簡単に処理できますが、少し読みにくいです。以下は、8 月 1 日以降に重大度または優先度が高い未解決の不具合を分類するクエリです。
String timeStamp = "2012-08-01T19:10:09.154Z";
Map<String, QueryFilter> filters = new HashMap<String, QueryFilter>();
filters.put("LastUpdateDate", new QueryFilter("LastUpdateDate", ">", timeStamp));
filters.put("State", new QueryFilter("State", "=", "Open"));
filters.put("Severity", new QueryFilter("Severity", "<=", "Major Problem"));
filters.put("Priority", new QueryFilter("Priority", "<=", "High Attention"));
// Evaluates to ((Severity <= Major Problem) OR (Priority <= High Attention)) AND ((LastUpdateDate > timeStamp) AND (State = Open))
QueryFilter complexFilter = filters.get("Severity").or(filters.get("Priority")).and(filters.get("LastUpdateDate").and(filters.get("State")));
大きな落とし穴は、コレクションである属性 (ユーザー ストーリーのタスクなど) を照会することです。クエリを連鎖させると、間違った結果が得られます。たとえば、進行中のタスクとブロックされたタスクの両方を含むユーザー ストーリーを探している場合、クエリは式を OR ステートメントとして評価します。これは、クエリが「ブロックされた状態のタスクをコレクション内で検索し、進行中のタスクを検索する」ように変換するために発生します。クエリは、最初の式の後、リストの範囲を狭めません。各式は、コレクション内のすべてのタスクを照会します。
これを回避する 1 つの方法は、クエリの 1 つを実行することです (進行中のすべてのタスクを取得するとします)。次に、そのリストをフィルタリングして、ブロックされているすべてのタスクを取得します。フィルター処理されたリストを取得したら、それらの各タスクがどのユーザー ストーリーに属しているかを確認できます。
参考文献:
上にリンクされている Rally Web サービス API。
http://developer.rallydev.com/help/java-toolkit-rally-rest-api (上記のクエリ フィルターを作成する基礎として、ページの最後にある最後の例を使用しました)。