PropertyObjectSearchDocument
Elasticsearch document PropertyObjectSearchDocument — rebuildable search projection полнотекстового
поиска объектов недвижимости публичного каталога (лента /lots, поиск по названию/номеру/адресу/
застройщику). Полнотекстовый поиск реализован на Elasticsearch (ADR-0059).
Назначение
Source of truth — CatalogPropertyObjectCard; проекция
хранит только индексируемые/фильтруемые/сортируемые поля карточки. Ключевые возможности поиска —
fuzzy (typo-tolerance), транслитерация кириллица↔латиница и алиасы для названий/адресов/застройщиков
(ADR-0059 п.1). Поиск проектов (ЖК/апарт-отелей) — отдельная проекция
projects.md.
Index
| Поле | Значение |
|---|---|
| Index alias | catalog-property-objects |
| Versioned index | catalog-property-objects-v1 |
| Owner service | catalog |
| Source of truth | CatalogPropertyObjectCard (catalog.property_object_cards) |
| Rebuild job | PropertyObjectSearchRebuildJob |
Document Id И Routing
- Document id:
Idкарточки (Guid объекта = id вchessboard); платформенная витрина не tenanted (ADR-0052 п.3), поэтому tenant-префикс не применяется. - Routing key:
ProjectId— объекты одного проекта колокализуются (эффективный пересчёт/переиндексация при изменении проекта). - Delete/tombstone: карточка
Status = Delistedили физическое удаление → удаление документа из индекса; переход вHidden→ документ остаётся, ноStatus=Hiddenвырезается security-trimming-ом до выдачи.
Поля
| Поле | Тип | Indexed | Stored | Analyzer | Source | Security |
|---|---|---|---|---|---|---|
Id | keyword | да | да | — | Id | — |
ProjectId | keyword | да | да | — | ProjectId | routing/filter |
DeveloperId | keyword | да | да | — | Developer.DeveloperId | scope-filter |
Title | text | да | нет | ru_translit_fuzzy | Title | — |
Number | text | да | нет | ru_translit_fuzzy | Number | — |
Address | text | да | нет | ru_translit_fuzzy | Address | — |
DeveloperName | text | да | нет | ru_translit_fuzzy | Developer.DeveloperName | — |
BuildingName | text | да | нет | ru_translit_fuzzy | Building.BuildingName | — |
RegionName | text | да | нет | ru_translit_fuzzy | project-card RegionName (денорм.) | — |
CityName | text | да | нет | ru_translit_fuzzy | project-card CityName (денорм.) | — |
SearchText | text | да | нет | ru_translit_fuzzy | Title ⊕ Number ⊕ Address ⊕ DeveloperName ⊕ RegionName ⊕ CityName (copy_to) | основной матч запроса searchTerm |
TypeName | keyword | да | да | — | Layout.TypeName | фильтр «тип» |
RoomsCount | short | да | да | — | Layout.RoomsCount | фильтр |
Price | double | да | да | — | Price | фильтр «ценовой диапазон» + сортировка |
PropertyObjectStatus | keyword | да | да | — | PropertyObjectStatus | фильтр доступности |
RegionId | keyword | да | да | — | project-card RegionId (денорм., ссылка на справочник handbook) | фильтр «регион» |
CityId | keyword | да | да | — | project-card CityId (денорм., ссылка на справочник handbook) | фильтр «город» |
DeliveryDate | date | да | да | — | DeliveryDate | фильтр/сортировка |
PromotionBoost | integer | да | да | — | PromotionBoost | ранжирование «Рекомендованные» |
DeveloperPriority | integer | да | да | — | DeveloperPriority | ранжирование |
PopularityScore | double | да | да | — | PopularityScore | сортировка «по популярности» |
PublishedAt | date | да | да | — | PublishedAt | сортировка «по дате» |
Status | keyword | да | да | — | Status | security-trimming (Published) |
SchemaVersion | integer | да | да | — | документ | версия схемы проекции |
UpdatedAt | date | да | да | — | карточка UpdatedAt | freshness watermark |
IndexedAt | date | да | да | — | индексатор | freshness |
Анализатор ru_translit_fuzzy: русская морфология + ICU-транслитерация (кириллица↔латиница) +
edge-ngram для typo-tolerance; словарь синонимов/алиасов застройщиков и типов (ADR-0059 п.1).
Source Events
| Event | Version | Transform |
|---|---|---|
PropertyObjectCardRecomputedEvent | v1 | upsert документа из текущего состояния CatalogPropertyObjectCard (маппинг полей выше) |
PropertyObjectCardRecomputedEvent (Status=Delisted) | v1 | delete документа |
Проекция наполняется инкрементально доменным событием карточки (тот же коммит, что пересчёт витрины) +
периодический/ручной PropertyObjectSearchRebuildJob для bootstrap и восстановления консистентности.
Freshness
- SLA:
search(секунды–минуты; eventual относительно PostgreSQL,FreshnessView). - Watermark:
UpdatedAtкарточки в документе. - Stale behavior: показать результаты с freshness-маркером; критичные для брони проверки статуса делает
crmв источнике, не поиск.
Security
- Tenant/brand/scope trimming выполняется до query execution (ADR-0059 п.3):
публичный поиск — только
Status = Published; developer-facing поиск — дополнительноDeveloperId == актор.CompanyId. - PII fields: none (в проекцию не кладутся ФИО/телефон/реквизиты; комиссия агента в индекс не попадает).
- Полнотекстовый поиск не индексирует secrets, tokens, payment/KYC data.
Rebuild
- Create versioned index
catalog-property-objects-v{N+1}(маппинг +ru_translit_fuzzy). - Backfill из
catalog.property_object_cards(Status != Delisted). - Validate counts/checksums против source.
- Atomically switch alias
catalog-property-objectsна новую версию (ADR-0029). - Keep previous index до окончания rollback-окна.
Деградация и частичный отказ
- Индекс недоступен. Полнотекстовый поиск объектов недвижимости зависит от Elasticsearch; при
недоступности индекса поиск деградирует — пользователю отдаётся признак «поиск временно недоступен», а
лента
/lotsбез текстового запроса (сортировки/фильтры по витринеcatalog.property_object_cards) продолжает работать через API каталога. «Примерную» FTS-выдачу из PostgreSQL не строим (FTS-колонок в источнике нет, ADR-0059). - Отставание проекции. Изменение карточки (публикация/скрытие/цена/доступность) видно в поиске после
доезда
PropertyObjectCardRecomputedEventи индексации (секунды–минуты); в окне рассинхронизации выдача помечается признаком свежести (FreshnessView). Критичную для брони проверку статуса делаетcrmв источнике, а не поиск (значениеPropertyObjectStatusв индексе может отставать). - Rebuild. Пересборка идёт в теневой индекс
catalog-property-objects-v{N+1}; алиасcatalog-property-objectsпереключается только после валидации счётчиков/чек-сумм — частичный или упавший rebuild не отдаёт пользователю неполный индекс, активным остаётся прежний до успешного switch.
Обратные ссылки
Автоссылки: где используется этот документ.
- Домен (CQRS) (1): Entity / Aggregate: CatalogPropertyObjectCard
- Поиск (2): PostSearchDocument, ProjectSearchDocument
- index.md (1): Catalog Service (Pin.Catalog)
Связанные документы
- catalog-property-object-card.md — source of truth; projects.md — проекция проектов (ЖК/апарт-отелей).
- ADR-0059 (Elasticsearch-проекции), ADR-0008 (search projection), ADR-0029 (alias strategy).
- Шаблон: search-document-template.md.