Поиск подстроки внутри объекта с использованием objectify

У меня есть объект, называемый lastName со значением "Benjamin". Есть ли способ объективировать это, если пользователь поставил "Бен" или "джем" или "Бенья". Я все еще могу найти этот объект, используя query.filter(). Я должен использовать запрос, так как есть другие критерии поиска iam.

Я увидел что-то в "Obgaektify", которое называется "начинается с". Но это не работает. Мы ценим любые предложения. Благодаря

Ответ 1

Нет запросов типа "LIKE" для подстроки, однако чувствительный к регистру "начинается с" можно моделировать, используя преимущества операторов > и < для индексов.

// 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 является наивысшим возможным символом юникода.

Ответ 2

Нет стандартного существующего индекса для подобных запросов. Кстати, вы всегда можете представить свои собственные. В этом случае вы можете:

  • добавить и синтетическое поле типа String[] lastNameIndex
  • добавить метод, помеченный как @PrePersist, который заполнит поле lastNameIndex всеми доступными комбинациями
  • Если вы хотите найти объекты, используя этот индекс, сделайте query.filter('lastNameIndex =', val)

Ответ 3

Полагая ответ от Криса и комментарий от Ника вместе, вот код для создания фильтра запросов для объективации V4:

public <T> Query<T> fieldStartsWith(Query<T> query, String field, String search){
    query = query.filter(field + " >=", search);
    return query.filter(field + " <", searchStr+"\ufffd");
}

Ответ 4

Я использовал метод токенизации. Вот код в 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.