feat(search): Elasticsearch-клиент (имя + контент) + oo search (#37) #41

Merged
eSlider merged 13 commits from feat/es-search#37 into main 2026-09-16 17:43:21 +01:00
Owner

Реализует F3 #37 (эпик #34): прямой Elasticsearch-клиент поиска по имени и содержимому документов + CLI oo search.

Что сделано

  • file_es.go: ESSearcher (stdlib net/http, ES REST 7.x). Search(SearchQuery):
    • multi_match по title^2 и document.attachment.content (при InContent);
    • фильтры tenantId и folders.folderId, _source id/title/folders;
    • highlight (фрагмент, теги <em> срезаются);
    • []SearchHit + Name() = "elasticsearch".
  • Модель Entry/Kind/SearchHit/SearchQuery/Searcher — из F1 #35, локально в
    file_es.go (F1 ещё не влит; переедет в file_core.go при мерже).
  • Конфиг: ONLYOFFICE_ES_URL, ONLYOFFICE_ES_INDEX (default files_file),
    ONLYOFFICE_TENANT; .env.example — только имена.
  • CLI oo search <query> [--content] [--folder id] [--limit N] [--json] через
    printTable/printJSON.
  • docs/elasticsearch.md — устройство поиска, туннель, env, грабли.

Доступ к ES (research, live)

  • ES внутри VM OnlyOffice (onlyoffice-v2), 127.0.0.1:9200, версия 7.16.3,
    cluster elasticsearch. Снаружи закрыт, SSH в VM — 127.0.0.1:32.
  • Туннель проверен: ssh -f -N -o ControlMaster=no -o ControlPath=none -p 32 -i ~/.ssh/id_ed25519 -L 9200:127.0.0.1:9200 root@127.0.0.1.
  • Индекс files_file (~39.8k док-в). Поля live: tenantId (не tenant_id),
    folders.folderId (строка), document.attachment.content (ingest-attachment,
    только Office-форматы).

Тесты

  • Unit (file_es_test.go): builder запроса (name-only / content / фильтры /
    лимит), парсер ответа и highlight, конфиг. PASS.
  • CLI (cmd/oo/search_test.go): регистрация команды и флагов, понятная ошибка
    без ONLYOFFICE_ES_URL. PASS.
  • Integration (file_es_integration_test.go, //go:build integration, skip без
    ONLYOFFICE_ES_URL): заливает временный xlsx (токены в имени и в ячейке),
    ждёт индексации, находит по имени и по контенту, проверяет highlight и что
    name-only не находит content-токен, удаляет проект. PASS live (ES туннель).
  • go build ./... && go vet ./... && go test -race ./... — зелёные. gitleaks — чисто.

Не мержу и не закрываю.

Реализует F3 #37 (эпик #34): прямой Elasticsearch-клиент поиска по имени и содержимому документов + CLI `oo search`. ## Что сделано - `file_es.go`: `ESSearcher` (stdlib net/http, ES REST 7.x). `Search(SearchQuery)`: - `multi_match` по `title^2` и `document.attachment.content` (при `InContent`); - фильтры `tenantId` и `folders.folderId`, `_source` id/title/folders; - `highlight` (фрагмент, теги `<em>` срезаются); - `[]SearchHit` + `Name() = "elasticsearch"`. - Модель `Entry`/`Kind`/`SearchHit`/`SearchQuery`/`Searcher` — из F1 #35, локально в `file_es.go` (F1 ещё не влит; переедет в `file_core.go` при мерже). - Конфиг: `ONLYOFFICE_ES_URL`, `ONLYOFFICE_ES_INDEX` (default `files_file`), `ONLYOFFICE_TENANT`; `.env.example` — только имена. - CLI `oo search <query> [--content] [--folder id] [--limit N] [--json]` через `printTable`/`printJSON`. - `docs/elasticsearch.md` — устройство поиска, туннель, env, грабли. ## Доступ к ES (research, live) - ES внутри VM OnlyOffice (`onlyoffice-v2`), `127.0.0.1:9200`, версия **7.16.3**, cluster `elasticsearch`. Снаружи закрыт, SSH в VM — `127.0.0.1:32`. - Туннель проверен: `ssh -f -N -o ControlMaster=no -o ControlPath=none -p 32 -i ~/.ssh/id_ed25519 -L 9200:127.0.0.1:9200 root@127.0.0.1`. - Индекс `files_file` (~39.8k док-в). Поля live: `tenantId` (не `tenant_id`), `folders.folderId` (строка), `document.attachment.content` (ingest-attachment, только Office-форматы). ## Тесты - Unit (`file_es_test.go`): builder запроса (name-only / content / фильтры / лимит), парсер ответа и highlight, конфиг. PASS. - CLI (`cmd/oo/search_test.go`): регистрация команды и флагов, понятная ошибка без `ONLYOFFICE_ES_URL`. PASS. - Integration (`file_es_integration_test.go`, `//go:build integration`, skip без `ONLYOFFICE_ES_URL`): заливает временный xlsx (токены в имени и в ячейке), ждёт индексации, находит по имени и по контенту, проверяет highlight и что name-only не находит content-токен, удаляет проект. **PASS live** (ES туннель). - `go build ./... && go vet ./... && go test -race ./...` — зелёные. gitleaks — чисто. Не мержу и не закрываю.
eSlider added 1 commit 2026-09-16 17:42:16 +01:00
feat(search): Elasticsearch searcher (name+content) and oo search (#37)
Release Please / Release Please (push) Skipped
Release / GoReleaser (push) Skipped
Tests / Secret scan (gitleaks) (push) Skipped
Tests / Test (Go 1.25) (push) Skipped
Tests / Test (Go stable) (push) Skipped
Tests / Secret scan (gitleaks) (pull_request) Successful in 4s
Tests / Test (Go 1.25) (pull_request) Successful in 18s
Tests / Test (Go stable) (pull_request) Successful in 20s
33b5c1ea97
eSlider merged commit 72c7cd5173 into main 2026-09-16 17:43:21 +01:00
eSlider deleted branch feat/es-search#37 2026-09-16 17:43:21 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: eSlider/go-onlyoffice#41