AACsearch
SDK

Go SDK

Как использовать AACsearch на Go — установка пакета, поиск товаров, управление индексами и синонимами.

Go SDK для AACsearch

Библиотека aacsearch-go позволяет добавить поиск товаров в ваше Go-приложение. Она поддерживает как простой поиск, так и полное управление индексами на серверной стороне.

Установка

Для Go 1.21 и выше:

go get github.com/aacsearch/aacsearch-go

Поиск товаров

Используйте SearchClient для выполнения поисковых запросов из приложения.

package main

import (
    "fmt"
    "log"
    "github.com/aacsearch/aacsearch-go"
)

func main() {
    // Создать клиент для поиска
    client, err := aacsearch.NewSearchClient(aacsearch.SearchClientOptions{
        BaseURL:   "https://app.aacsearch.com",
        APIKey:    "ss_search_your_key_here",
        IndexSlug: "products",
    })
    if err != nil {
        log.Fatal(err)
    }

    // Простой поиск
    result, err := client.Search(aacsearch.SearchParams{
        Q: "laptop",
    })
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Найдено %d товаров\n", result.Found)
    for _, hit := range result.Hits {
        fmt.Printf("  - %s\n", hit.Document)
    }

    // Поиск с фильтрами и сортировкой
    result, err = client.Search(aacsearch.SearchParams{
        Q:        "phone",
        FilterBy: "price:[100..500]",
        SortBy:   "price:asc",
        PerPage:  20,
    })
    if err != nil {
        log.Fatal(err)
    }

    // Несколько поисков в одном запросе
    results, err := client.MultiSearch([]aacsearch.SearchParams{
        {Q: "nike", QueryBy: "title"},
        {Q: "adidas", QueryBy: "title", FilterBy: "in_stock:=true"},
    })
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Получено %d результатов\n", len(results.Results))
}

Управление индексом (серверная сторона)

Используйте AdminClient для создания и управления индексом. Используйте только на сервере, не встраивайте в браузерный код.

package main

import (
    "log"
    "github.com/aacsearch/aacsearch-go"
)

func main() {
    // Создать админ-клиент
    admin, err := aacsearch.NewAdminClient(aacsearch.AdminClientOptions{
        BaseURL:   "https://app.aacsearch.com",
        APIKey:    "aa_admin_your_key_here",
        ProjectID: "org_xxx",
    })
    if err != nil {
        log.Fatal(err)
    }

    // Создать индекс с полями для фильтрации и сортировки
    index, err := admin.CreateIndex(aacsearch.CreateIndexInput{
        Slug:        "products",
        DisplayName: "Products",
        Fields: []aacsearch.FieldDefinition{
            {Name: "title", Type: "string"},
            {Name: "price", Type: "float", Facet: boolPtr(true)},
            {Name: "brand", Type: "string", Facet: boolPtr(true)},
            {Name: "category", Type: "string", Facet: boolPtr(true)},
        },
        DefaultSortingField: "price",
    })
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Индекс создан: %s", index.ID)

    // Добавить товары в индекс
    err = admin.UpsertDocument(index.ID, "doc_001", map[string]interface{}{
        "title":    "MacBook Pro",
        "price":    2499.00,
        "brand":    "Apple",
        "category": "Laptops",
    })
    if err != nil {
        log.Fatal(err)
    }

    // Пакетное добавление товаров
    docs := []map[string]interface{}{
        {
            "id":       "doc_002",
            "title":    "iPhone 15",
            "price":    1199.00,
            "brand":    "Apple",
            "category": "Phones",
        },
        {
            "id":       "doc_003",
            "title":    "Galaxy S24",
            "price":    999.00,
            "brand":    "Samsung",
            "category": "Phones",
        },
    }
    err = admin.BatchUpsertDocuments(index.ID, docs)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("Товары добавлены")
}

// Вспомогательная функция для указателя на bool
func boolPtr(b bool) *bool {
    return &b
}

Синонимы и курации

// Добавить синонимы
err := admin.UpsertSynonyms(index.ID, []aacsearch.Synonym{
    {Root: "laptop", Replacements: []string{"notebook", "ultrabook"}},
    {Root: "phone", Replacements: []string{"smartphone", "мобильный телефон"}},
})
if err != nil {
    log.Fatal(err)
}

// Закрепить товар в результатах для конкретного запроса
err = admin.UpsertCurations(index.ID, []aacsearch.Curation{
    {Query: "macbook", PinnedIds: []string{"doc_001"}},
})
if err != nil {
    log.Fatal(err)
}

Управление API-ключами

// Создать ключ поиска
key, err := admin.CreateKey(aacsearch.CreateKeyInput{
    Name:      "My Search Key",
    Scopes:    []string{"search"},
    IndexSlug: "products",
})
if err != nil {
    log.Fatal(err)
}
log.Printf("Ключ создан: %s (сохраните его в безопасном месте)", key.RawKey)

// Список ключей
keys, err := admin.ListKeys()
if err != nil {
    log.Fatal(err)
}

// Отозвать ключ
err = admin.RevokeKey(key.ID)
if err != nil {
    log.Fatal(err)
}

Обработка ошибок

import (
    "errors"
    "github.com/aacsearch/aacsearch-go"
)

result, err := client.Search(aacsearch.SearchParams{Q: "laptop"})
if err != nil {
    var sdkErr *aacsearch.Error
    if errors.As(err, &sdkErr) {
        switch sdkErr.Code {
        case "unauthorized":
            log.Println("Ошибка: неверный API-ключ")
        case "rate_limit_exceeded":
            log.Println("Превышен лимит запросов, подождите")
        case "index_not_found":
            log.Println("Индекс не найден")
        default:
            log.Printf("Ошибка API (%s): %s", sdkErr.Code, sdkErr.Message)
        }
    }
}

Безопасность ключей

  • Ключи поиска (ss_search_*) — безопасны для использования в API
  • Административные ключи (aa_admin_*) — только на сервере
  • Храните ключи в переменных окружения или секретах конфигурации
  • Отозвите скомпрометированный ключ в панели управления

On this page