Поиск подстроки внутри объекта с использованием 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.