Здесь есть несколько хитрых трюков.Рассмотрим эту расширенную модель:
class Person(db.Model):
first_name = db.StringProperty()
last_name = db.StringProperty()
middle_name = db.StringProperty()
names_lower = db.StringListProperty()
Вам нужно будет синхронизировать names_lower с реальными полями, например:
p.names_lower = [p.first_name.lower(), p.last_name.lower(),
p.middle_name.lower()]
Вы можете сделать это более элегантно с помощью DerivedProperty .
И теперь ваш запрос:
term = self.request.get('term').lower()
query = Person.all()
query.filter('names_lower >=', term)
query.filter('names_lower <=', unicode(term) + u"\ufffd")
Это дает вам:
- Соответствие по всем 3 свойствам с одним индексом
- Совпадения без учета регистра
- Совпадения с подстановочным знаком
Таким образом, запрос «smi» вернет любого человека с любым именем, начинающимся с «smi» в любом случае.
Копирование имен в нижнем регистре в ListProperty позволяет выполнять поиск без учета регистра и позволяет искать все 3 поля одним запросом.«\ ufffd» - это максимально возможный символ Юникода, поэтому это верхний предел для соответствия нашей подстроки.Если по какой-то причине вы хотите точное совпадение, вместо этого укажите 'names_lower =', term
.
Редактировать :
Как мне искать то же самое в моем хранилище данных(так как мне нужно посмотреть на каждое поле и, возможно, для комбинированного значения 3 полей)?Как оптимизировать такой запрос?
Это уже учтено в исходном решении.Взяв 3 поля и скопировав их в один ListProperty, мы, по сути, создаем один индекс с несколькими записями на человека.Если у нас есть человек по имени Боб Дж. Смит, у него будет 3 попадания в нашем индексе:
- names_lower = bob
- names_lower = j
- names_lower = smith
Это исключает необходимость выполнения отдельных запросов для каждого поля.
Мне также не ясно, каким должен быть формат ответа.
Внимательно прочитайте документы .Форматирование вывода для jQuery должно быть довольно простым.Ваш источник данных будет строкой, указывающей URL, и вы захотите отформатировать ответ как JSON.