Class: Leann::Searcher

Inherits:
Object
  • Object
show all
Defined in:
lib/leann/searcher.rb

Overview

Handles search operations on an index

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(index) ⇒ Searcher

Returns a new instance of Searcher.

Parameters:



12
13
14
15
16
17
18
# File 'lib/leann/searcher.rb', line 12

def initialize(index)
  @index = index
  @backend = nil
  @embedding_provider = nil
  @offsets = nil
  @passages_cache = nil
end

Instance Attribute Details

#indexIndex (readonly)

Returns:



9
10
11
# File 'lib/leann/searcher.rb', line 9

def index
  @index
end

Instance Method Details

#search(query, limit: 5, threshold: nil, filters: nil) ⇒ SearchResults

Search the index

Examples:

Basic search

results = searcher.search("machine learning")

With options

results = searcher.search("auth", limit: 10, threshold: 0.7)

With metadata filters

results = searcher.search("query", filters: { category: "docs" })

Parameters:

  • query (String)

    Search query

  • limit (Integer) (defaults to: 5)

    Maximum results (default: 5)

  • threshold (Float, nil) (defaults to: nil)

    Minimum score threshold (0.0-1.0)

  • filters (Hash, nil) (defaults to: nil)

    Metadata filters

Returns:



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/leann/searcher.rb', line 36

def search(query, limit: 5, threshold: nil, filters: nil)
  start_time = Time.now

  # Compute query embedding
  query_embedding = embedding_provider.compute([query]).first

  # Load all passages for on-the-fly embedding computation
  passages = load_all_passages

  # Search with on-the-fly embedding recomputation
  raw_results = backend.search(
    query_embedding,
    embedding_provider: embedding_provider,
    passages: passages,
    limit: limit * 2
  )

  # Load passages and build results
  results = raw_results.map do |id, score|
    passage = load_passage(id)
    next unless passage

    SearchResult.new(
      id: id,
      text: passage[:text],
      score: score,
      metadata: passage[:metadata] || {}
    )
  end.compact

  # Apply threshold filter
  results = results.select { |r| r.score >= threshold } if threshold

  # Apply metadata filters
  results = apply_filters(results, filters) if filters

  # Limit and sort results
  results = results.sort.first(limit)

  duration = Time.now - start_time

  SearchResults.new(results, query: query, duration: duration)
end