Lookup
Поле типа Lookup автоматически получает значение поля из связанной записи.
Основные характеристики
- Тип данных: Зависит от исходного поля
- Источник: Поле из связанной записи
- Режим: Только для чтения
- Обновление: Автоматическое при изменении связанной записи
- Множественные значения: Поддержка массивов при множественных связях
Как работает Lookup
Lookup позволяет "подтянуть" значение поля из связанной записи без необходимости делать дополнительные запросы.
Заказ → Клиент → Email клиента
Вместо того чтобы делать два запроса (получить заказ, затем клиента), Lookup автоматически получает email клиента в записи заказа.
Настройки поля
При создании поля типа "Lookup" доступны следующие настройки:
- Название поля: Отображаемое имя поля
- Системное имя: Уникальный идентификатор для API
- Описание: Подсказка для пользователей
- Поле связи: Поле типа Relation в текущей коллекции
- Поле для получения: Поле из связанной записи
- Множественные значения: Если связь множественная (One-to-Many)
Примеры использования
Email клиента в заказе
{
"name": "customer_email",
"type": "lookup",
"relationField": "customer",
"lookupField": "email"
}
Структура:
- Коллекция
ordersимеет полеcustomer(Relation → users) - Lookup
customer_emailполучаетemailиз связанного пользователя
Название категории в товаре
{
"name": "category_name",
"type": "lookup",
"relationField": "category",
"lookupField": "name"
}
Имя автора в статье
{
"name": "author_name",
"type": "lookup",
"relationField": "author",
"lookupField": "full_name"
}
Цены товаров в заказе
{
"name": "item_prices",
"type": "lookup",
"relationField": "items",
"lookupField": "price",
"multiple": true
}
Работа через API
Получение значения Lookup
const order = await emd.database.collection('orders').get(orderId);
console.log(order.customer_email); // "customer@example.com"
console.log(order.customer_name); // "Иван Иванов"
Множественные значения
const order = await emd.database.collection('orders').get(orderId);
console.log(order.item_names);
// ["Ноутбук Dell XPS 15", "Мышь Logitech", "Клавиатура"]
console.log(order.item_prices);
// [89990, 1990, 3990]
Поиск по Lookup полю
// Найти заказы клиента с определенным email
const orders = await emd.database.collection('orders').find({
customer_email: 'customer@example.com'
});
// Найти товары определенной категории
const products = await emd.database.collection('products').find({
category_name: 'Электроника'
});
Вложенные Lookup
Lookup из вложенной связи
{
"name": "customer_city",
"type": "lookup",
"relationField": "customer",
"lookupField": "address.city"
}
Структура:
orders.customer→usersusers.address→ JSON поле сcity- Lookup получает
cityиз адреса клиента
Цепочка Lookup
// В коллекции orders
{
"name": "customer_manager_name",
"type": "lookup",
"relationField": "customer",
"lookupField": "manager.name"
}
Структура:
orders.customer→customerscustomers.manager→users- Lookup получает имя менеджера клиента
Примеры со сложными структурами
Информация о товарах в заказе
// Коллекция: orders
// Поля:
// - items: Relation (Many) → products
// - item_names: Lookup → items.name
// - item_prices: Lookup → items.price
// - item_images: Lookup → items.image
const order = await emd.database.collection('orders').get(orderId);
console.log(order.item_names);
// ["Товар 1", "Товар 2", "Товар 3"]
console.log(order.item_prices);
// [1000, 2000, 3000]
Данные автора статьи
// Коллекция: articles
// Поля:
// - author: Relation → users
// - author_name: Lookup → author.name
// - author_email: Lookup → author.email
// - author_avatar: Lookup → author.avatar
const article = await emd.database.collection('articles').get(articleId);
console.log(`Автор: ${article.author_name}`);
console.log(`Email: ${article.author_email}`);
Комбинация с формулами
Полная информация о клиенте
{
"name": "customer_info",
"type": "formula",
"formula": "`${record.customer_name} (${record.customer_email})`",
"resultType": "string"
}
Где customer_name и customer_email — это Lookup поля.
Общая стоимость товаров
{
"name": "items_total",
"type": "formula",
"formula": "record.item_prices.reduce((sum, price) => sum + price, 0)",
"resultType": "number"
}
Где item_prices — это Lookup поле с множественными значениями.
Обновление Lookup полей
Lookup поля обновляются автоматически при изменении связанной записи:
// Изменить email клиента
await emd.database.collection('users').update(customerId, {
email: 'newemail@example.com'
});
// Все заказы этого клиента автоматически получат новый email в customer_email
const order = await emd.database.collection('orders').get(orderId);
console.log(order.customer_email); // "newemail@example.com"
Производительность
Преимущества Lookup
- Не требует дополнительных запросов
- Автоматическое обновление при изменении источника
- Удобство использования в интерфейсе
Недостатки
- Увеличивает размер документа
- Может замедлить запись при большом количестве Lookup полей
Оптимизация
// Получить только нужные поля
const order = await emd.database.collection('orders').get(orderId, {
fields: ['customer_name', 'customer_email', 'total']
});
Индексация
// Создать индекс для Lookup поля
await emd.database.collection('orders').createIndex({
customer_email: 1
});
Типичные сценарии
CRM: Информация о компании в контакте
{
"name": "company_name",
"type": "lookup",
"relationField": "company",
"lookupField": "name"
},
{
"name": "company_industry",
"type": "lookup",
"relationField": "company",
"lookupField": "industry"
}
E-commerce: Данные товара в позиции заказа
{
"name": "product_name",
"type": "lookup",
"relationField": "product",
"lookupField": "name"
},
{
"name": "product_price",
"type": "lookup",
"relationField": "product",
"lookupField": "price"
},
{
"name": "product_image",
"type": "lookup",
"relationField": "product",
"lookupField": "main_image"
}
Проекты: Участники команды
{
"name": "team_member_names",
"type": "lookup",
"relationField": "team_members",
"lookupField": "name",
"multiple": true
},
{
"name": "team_member_emails",
"type": "lookup",
"relationField": "team_members",
"lookupField": "email",
"multiple": true
}
Отображение в интерфейсе
Простое значение
const order = await emd.database.collection('orders').get(orderId);
console.log(`Клиент: ${order.customer_name}`);
console.log(`Email: ${order.customer_email}`);
Множественные значения
const order = await emd.database.collection('orders').get(orderId);
const itemsList = order.item_names.map((name, index) => `
<li>${name} - ${order.item_prices[index]} ₽</li>
`).join('');
console.log(`<ul>${itemsList}</ul>`);
Ограничения
- Нельзя делать Lookup из Lookup (только один уровень вложенности)
- Максимальная глубина вложенности: 2 уровня (relation.field.subfield)
- Lookup поля нельзя редактировать напрямую
- При удалении связанной записи Lookup становится null
Рекомендации
- Используйте Lookup для часто используемых полей из связанных записей
- Не создавайте слишком много Lookup полей (влияет на производительность)
- Используйте Lookup вместо populate для простых случаев
- Создавайте индексы для Lookup полей, по которым часто ищете
- Документируйте структуру связей и Lookup полей
Отличие от других типов
- Lookup vs Formula: Lookup получает значение из связанной записи, Formula вычисляет
- Lookup vs Rollup: Lookup для одного значения, Rollup для агрегации множества
- Lookup vs Relation: Lookup показывает конкретное поле, Relation показывает всю запись