0

このクエリは機能します。fullPathフィールドはList<String>:です。

    KeyLookup lookup 
        = ofy().load().type(KeyLookup.class).filter("fullPath IN", key.getFullPath()).first().get();

上記のクエリは、と同じString要素をList<String>持つエンティティもフェッチしkey.getFullPath()ますが、リストに同じ文字列があり、リストにさらに文字列があるエンティティもフェッチします。

「これ以上でもそれ以下でもない」など、リストにまったく同じ要素を持つエンティティのみをフィルタリングするにはどうすればよいですか。

アップデート:

例えば

1つのエンティティ(たとえばObject1)フィールドfullPathには次のものが含まれます。

  • "1"
  • "二"
  • "三"

別のエンティティ(たとえばObject2)フィールドfullPathには次のものが含まれます。

  • "1"
  • "二"
  • "三"
  • "四"

また、key.getFullPathには次のものが含まれます。

  • "1"
  • "二"
  • "三"
  • "四"

次に、上記のクエリが返さObject1れますObject2が、必要なのは、返されるだけです。Object2

4

2 に答える 2

3

完全に一致する必要があると仮定すると(値がこれ以上、値が少なくなることはありません)、これを実装する「ネイティブデータストア」の方法はありません。INはor演算を取得し、filter()を複数回呼び出すと、and演算が生成されます。どちらも完全には一致しません。ただし、方法はいくつかあります。

オプション1:リストを単一のインデックス付きプロパティに結合する

リスト内のすべてのアイテムを単一の値に連結し、それを合成インデックス付きプロパティとして格納します。順序や大文字小文字の重要性に応じて、正規化する必要があるかもしれません。リストプロパティではなく、そのプロパティをクエリします。

これは、連結された値が500文字未満に収まることが保証されている場合にのみ機能します。ありそうもないようです。代わりにあなたはおそらく欲しい...

オプション2:リストのハッシュにインデックスを付けてクエリを実行する

  1. のようなすべてのリスト値のハッシュを保持する合成プロパティを作成しますfullPathHash。暗号的に安全である必要はありません。MD5は問題ありません。
  2. listプロパティを更新するたびに、ハッシュを更新してください。
  3. インデックスを作成しfullPathHashます。listプロパティにインデックスを付ける必要はありません。
  4. アイテムのリストを照会するときは、ハッシュを照会してください。衝突が発生する可能性があるため、クエリ後のチェックを実行してリストが等しいことを確認し、誤検知をスキップします。
于 2012-10-19T15:51:44.920 に答える
1

クエリ内の2つのリストを比較する場合、実際に内部で発生するのは、データストアがフィルターリスト内の値ごとに複数のクエリを実行するためです。したがって、をクエリするObject2と、の値ごとに4つのクエリが実行されますObject2。はのObject1「サブセット」であるObject2ため、クエリにも一致します。Object1これが、との両方を取得する理由ですObject2

AND完全一致を強制するために、演算子を使用するようにクエリを変更できます。したがって、次のようにすることができます。

Query<KeyLookup> q = ofy().load().type(KeyLookup.class);
for (String f : key.getFullPath()) {
    q = q.filter("fullPath", f);
}
KeyLookup lookup = q.first().get();

お役に立てれば。

于 2012-10-18T10:33:33.453 に答える