0

此查询有效,该fullPath字段是List<String>

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

上面的查询还获取在as with中具有相同String元素的实体,但是它还获取列表中具有相同字符串的那些实体,并在列表中获取更多字符串。List<String>key.getFullPath()

如何仅过滤列表中具有完全相同元素的实体,例如“不多不少”

更新:

例如

一个实体(比如 Object1)字段 fullPath 包含:

  • “一”
  • “二”
  • “三”

另一个实体(比如 Object2)字段 fullPath 包含:

  • “一”
  • “二”
  • “三”
  • “四”

key.getFullPath 包含:

  • “一”
  • “二”
  • “三”
  • “四”

然后上面的查询将返回Object1Object2但是我需要的是它只返回Object2

4

2 回答 2

3

假设您想要完全匹配(没有更多的值,也没有更少的值),没有“本机数据存储”方式来实现这一点。IN 给你一个or操作,多次调用 filter() 给你一个and操作——它们都不是完全匹配的。但是,有办法。

选项 1:将列表加入单个索引属性

将列表中的所有项目连接成单个值并将其存储为合成索引属性。也许您需要根据订单或大小写的重要性对其进行规范化。查询该属性,而不是列表属性。

这仅在保证连接值小于 500 个字符时才有效。似乎不太可能。相反,您可能想要...

选项 2:对列表的哈希进行索引和查询

  1. 创建一个合成属性,其中包含所有列表值的哈希,例如fullPathHash. 它不需要加密安全;MD5 没问题。
  2. 每当您更新列表属性时,都会更新哈希。
  3. 索引fullPathHash;您不需要索引列表属性。
  4. 当您查询项目列表时,请查询哈希。由于可能存在冲突,请进行查询后检查以确保列表相等并跳过任何误报。
于 2012-10-19T15:51:44.920 回答
1

这是意料之中的,因为在比较查询中的两个列表时,实际上发生的事情是数据存储区为过滤器列表中的每个值触发多个查询。因此,当您查询 时Object2,将对 中的每个值执行四个查询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 回答