search

package
v0.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: Unlicense Imports: 11 Imported by: 0

Documentation

Overview

Package search implements profile search indexing and ranking used by the relay package to serve NIP-50 search queries: a pluggable Backend interface, a batching Service that indexes profile updates asynchronously, and a ReadOnlyService decorator for relay instances that should query but never index.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Backend

type Backend interface {
	Initialize(ctx context.Context) error
	IndexProfile(ctx context.Context, doc *ProfileDocument) error
	BulkIndex(docs []*ProfileDocument) error
	FindProfiles(ctx context.Context, query string, limit int) ([]string, error)
	DeleteProfile(ctx context.Context, pubkey string) error
	UpdateScore(ctx context.Context, pubkey string, score int64) error
	DeleteIndex(ctx context.Context) error
	IndexProfileWithMetrics(ctx context.Context, doc *ProfileDocument, getMetricsFunc func(pubkey string) (int64, error)) error
}

Backend defines the methods we use from the infrastructure layer. This allows mocking for tests and swapping the underlying search engine.

type Indexer

type Indexer interface {
	IndexProfile(ctx context.Context, profile *ProfileDocument) error
	UpdateScore(ctx context.Context, pubkey string, score int64) error
	// IndexProfileWithMetrics calculates total score using existing BoltDB metrics.
	IndexProfileWithMetrics(ctx context.Context, profile *ProfileDocument, getMetricsFunc func(pubkey string) (int64, error)) error
	// DeleteProfile removes a single profile's document from the index.
	DeleteProfile(ctx context.Context, pubkey string) error
}

Indexer defines how we send data to the search engine. R1 Implementation: Direct HTTP calls to the search backend via a Go Channel buffer.

type MetadataContent

type MetadataContent struct {
	Name        string `json:"name"`
	DisplayName string `json:"display_name"`
	About       string `json:"about"`
	Nip05       string `json:"nip05"`
	Lud16       string `json:"lud16"`
	Picture     string `json:"picture"`
}

type ProfileDocument

type ProfileDocument struct {
	ID          string `json:"id"` // The Pubkey (Primary Key)
	Npub        string `json:"npub"`
	Name        string `json:"name"`
	DisplayName string `json:"display_name"`
	About       string `json:"about"` // Truncated to max length
	Nip05       string `json:"nip05"`
	Lud16       string `json:"lud16"`
	Picture     string `json:"picture"`
	Score       int64  `json:"score"`      // Unified total score (Base + Verify)
	IndexedAt   int64  `json:"indexed_at"` // Unix timestamp
}

ProfileDocument represents the structure stored in the search engine

func FromEvent

func FromEvent(ev *nip01.Event) *ProfileDocument

FromEvent converts a Nostr Event (Kind 0) into a Search Document.

type ReadOnlyService

type ReadOnlyService struct {
	// contains filtered or unexported fields
}

ReadOnlyService wraps a Service and silently drops all write operations. Read operations (FindProfiles) are delegated to the inner service. Use this for relay instances that should query the search backend but never index.

func NewReadOnlyService

func NewReadOnlyService(inner Service) *ReadOnlyService

NewReadOnlyService returns a Service that no-ops all writes, logging through the process-global logger.

func NewReadOnlyServiceWithLogger added in v0.2.2

func NewReadOnlyServiceWithLogger(inner Service, logger zerolog.Logger) *ReadOnlyService

NewReadOnlyServiceWithLogger is like NewReadOnlyService but logs through the given logger instead of the process-global one, so callers (tests in particular) can route this message through their own logger rather than having it dumped as raw JSON to stdout/stderr.

func (*ReadOnlyService) DeleteIndex

func (r *ReadOnlyService) DeleteIndex(ctx context.Context) error

func (*ReadOnlyService) DeleteProfile added in v0.2.2

func (r *ReadOnlyService) DeleteProfile(ctx context.Context, pubkey string) error

func (*ReadOnlyService) FindProfiles

func (r *ReadOnlyService) FindProfiles(ctx context.Context, query string, limit int) ([]string, error)

func (*ReadOnlyService) IndexProfile

func (r *ReadOnlyService) IndexProfile(ctx context.Context, doc *ProfileDocument) error

func (*ReadOnlyService) IndexProfileWithMetrics

func (r *ReadOnlyService) IndexProfileWithMetrics(ctx context.Context, doc *ProfileDocument, getMetricsFunc func(pubkey string) (int64, error)) error

func (*ReadOnlyService) Initialize

func (r *ReadOnlyService) Initialize(ctx context.Context) error

func (*ReadOnlyService) Shutdown

func (r *ReadOnlyService) Shutdown(ctx context.Context) error

func (*ReadOnlyService) UpdateScore

func (r *ReadOnlyService) UpdateScore(ctx context.Context, pubkey string, score int64) error

type Searcher

type Searcher interface {
	FindProfiles(ctx context.Context, query string, limit int) ([]string, error)
}

Searcher defines how we query data. R1 Implementation: HTTP GET to the search backend.

type Service

type Service interface {
	Indexer
	Searcher
	// Initialize ensures the index exists with correct settings
	Initialize(ctx context.Context) error
	Shutdown(ctx context.Context) error
	DeleteIndex(ctx context.Context) error
}

Service combines both for the Relay to use.

type ServiceImpl

type ServiceImpl struct {
	// contains filtered or unexported fields
}

func NewService

func NewService(client Backend, batchSize int, maxChSize int) *ServiceImpl

func (*ServiceImpl) DeleteIndex

func (s *ServiceImpl) DeleteIndex(ctx context.Context) error

func (*ServiceImpl) DeleteProfile

func (s *ServiceImpl) DeleteProfile(ctx context.Context, pubkey string) error

func (*ServiceImpl) FindProfiles

func (s *ServiceImpl) FindProfiles(ctx context.Context, query string, limit int) ([]string, error)

FindProfiles implements Searcher.

func (*ServiceImpl) IndexProfile

func (s *ServiceImpl) IndexProfile(ctx context.Context, doc *ProfileDocument) error

IndexProfile implements Indexer. It is non-blocking. If channel is full, it drops the update to preserve Relay stability.

func (*ServiceImpl) IndexProfileWithMetrics

func (s *ServiceImpl) IndexProfileWithMetrics(ctx context.Context, doc *ProfileDocument, getMetricsFunc func(pubkey string) (int64, error)) error

IndexProfileWithMetrics adds any existing verified metrics (Nip05/Lud16/Picture) to the base score before pushing to the index channel.

func (*ServiceImpl) Initialize

func (s *ServiceImpl) Initialize(ctx context.Context) error

func (*ServiceImpl) Shutdown

func (s *ServiceImpl) Shutdown(ctx context.Context) error

func (*ServiceImpl) UpdateScore

func (s *ServiceImpl) UpdateScore(ctx context.Context, pubkey string, score int64) error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL