Часто встречается кейс, когда нужен фильтр в search по дополнительным полям элемента приложения. Например, нам нужно отфильтровать приложение "Компании" по полю "Менеджер", id которого равен текущему пользователю:
Код:
const currentUser = await System.users.getCurrentUser();
const currUserID = currentUser.id;
const companies = await Context.fields.companies.app.search()
.where((f, g) => g.and(
f.__deletedAt.eq(null),
))
.size(1000)
.all()
.then(e => e.filter(e => e.data.manager!.id == currUserID))
В итоге мы уже в search отфильтровали по более сложному фильтру наше приложение и получили нужные элементы.
Так как во then можно прописывать функции, то можно сразу же выполнять какие-то операции с полями нашего приложения:
Код:
let promises: Promise<void>[] = [];
await Namespace.app.promises.search()
.where((f, g) => g.and(
f.__deletedAt.eq(null),
))
.size(100)
.all()
.then((e) => {
e.forEach(async (e) => {
if (e.data.numb == undefined) {
await e.delete()
} else {
e.data.numb! *= 2;
}
promises.push(e.save())
})
})
if (promises.length > 0) {
await Promise.all(promises)
}
В примере выше, во then мы удаляем элементы приложения, у которых поле numb не заполнено, а у остальных умножаем это поле на 2.
save() (сохранение элемента после изменений) для большого количества элементов не получится. Поэтому тут нужно будет привязать переменную к параметру .size(), и увеличивать ее выполняя функцию в цикле.
Кроме .then() после .all() нам доступен метод .catch(), в котором мы можем отслеживать ошибки и выполнять что-то, если во .then() что-то пошло не так. В примере ниже мы ищем элементы приложений, у которых поле numb равно 100000, и записываем в контекстную переменную значение numb * 3. Если numb с таким значением нет, то мы переходим в .catch(), где мы можем записать ошибку и найти альтернативное значение numb и записать в Context.data.counter результат с этим значением numb.
Код:
await Namespace.app.promises.search()
.where((f, g) => g.and(
f.__deletedAt.eq(null),
))
.size(100)
.all()
.then((e) => {
const find = e.filter(i => i.data.numb! == 100000)
Context.data.counter = find[0].data.numb! * 3
})
.catch(async (e) => {
Context.data.error = e.message;
const app = await Namespace.app.promises.search()
.where((f, g) => g.and(
f.__deletedAt.eq(null),
))
.size(80)
.all()
const find = app.filter(i => i.data.numb! == 14544)
Context.data.counter = find[0].data.numb! * 3
})
Заключение
Благодаря использованию .then() и .catch() мы получаем более широкие возможности метода .search(), а также отслеживать ошибки при поиске элементов приложений. При грамотно составленных .then() и .catch(), думаю, можно добиться более предсказуемого, вариативного и поддерживаемого кода: меньше боли при поддержке тем кто написал и тем, кто будет дорабатывать и т.д.
К сожалению, реальных нагруженных кейсов у меня еще нет, только небольшие запросы, т.к. пришел к этой теме недавно. Если у кого-то что-то есть, примеры, то было очень круто увидеть, или понять, что использование этих методов не нужно или даже бесполезно.