10

我有一个名为 lastName 的实体,其值为“Benjamin”。如果用户输入“Ben”或“jam”或“Benja”,有没有办法客观化。我仍然可以使用 query.filter() 找到这个实体。我必须使用查询,因为我正在检查其他搜索条件。

我在“Obgaektify”中看到了一些名为“starts with”的操作符。但它不工作。任何建议,将不胜感激。谢谢

4

4 回答 4

12

子字符串没有“LIKE”类型的查询,但是可以通过利用索引上的and运算符来模拟区分大小写的“开头为”。><

// The start string
String searchStr = "Ben";

// emulate a "starts with" query
Query q = new Query("MyEntity")
q.addFilter("name", Query.FilterOperator.GREATER_THAN_OR_EQUAL, searchStr);
q.addFilter("name", Query.FilterOperator.LESS_THAN, searchStr + "\ufffd");

查询将“搜索”name以“Ben”开头且小于 的项目的属性"Ben\ufffd",其中\ufffd是最高可能的 unicode 字符。

于 2011-08-10T18:22:20.853 回答
2

对于类似包含的查询,没有标准的现有索引。顺便说一句,你总是可以介绍你自己的。在这种情况下,您可以这样做:

  1. 添加和合成字段,例如String[] lastNameIndex
  2. 添加标记为的方法将用所有可用组合@PrePersist填充字段lastNameIndex
  3. 当您想使用此索引查找实体时,请执行query.filter('lastNameIndex =', val)
于 2011-08-10T18:17:12.200 回答
0

将 Chris 的答案和 Nick 的评论放在一起,下面是为 objectify V4 构建查询过滤器的代码:

public <T> Query<T> fieldStartsWith(Query<T> query, String field, String search){
    query = query.filter(field + " >=", search);
    return query.filter(field + " <", searchStr+"\ufffd");
}
于 2013-02-23T08:43:44.670 回答
0

我使用了标记化方法。这是Java中的代码:

private String tokenize(String phrase) {
StringBuilder tokens = new StringBuilder();
try {
  for (String word : phrase.split(" ")) {
    if (word.length() < 1) {
      continue;
    }
    int j = 1;
    while (true) {
      for (int i = 0; i < word.length() - j + 1; i++) {
        tokens.append(word.substring(i, i + j)).append(" ");
      }
      if (j == word.length()) {
        break;
      }
      j++;
    }
  }
} catch (Throwable t) {
  t.printStackTrace();
}
return tokens.toString();}

这允许定义一个可索引字段,然后处理标准 Ofy 查询和 SearchService。

于 2015-10-27T09:57:01.647 回答