Class: XapianDb::QueryParser

Inherits:
Object
  • Object
show all
Defined in:
lib/xapian_db/query_parser.rb

Overview

Parse a query expression and create a xapian query object

Author:

  • Gernot Kogler

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(database) ⇒ QueryParser

Constructor

Parameters:



15
16
17
18
19
20
21
# File 'lib/xapian_db/query_parser.rb', line 15

def initialize(database)
  @db = database

  # Set the parser options
  @query_flags = 0
  XapianDb::Config.query_flags.each { |flag| @query_flags |= flag }
end

Instance Attribute Details

#spelling_suggestionString (readonly)

The spelling corrected query (if a language is configured)

Returns:

  • (String)


11
12
13
# File 'lib/xapian_db/query_parser.rb', line 11

def spelling_suggestion
  @spelling_suggestion
end

Instance Method Details

#parse(expression) ⇒ Xapian::Query

Parse an expression

Returns:



25
26
27
28
29
30
31
32
33
34
35
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
# File 'lib/xapian_db/query_parser.rb', line 25

def parse(expression)
  return nil if expression.nil? || expression.strip.empty?
  parser            = Xapian::QueryParser.new
  parser.database   = @db.reader
  parser.default_op = Xapian::Query::OP_AND # Could be made configurable
  if XapianDb::Config.stemmer
    parser.stemmer           = XapianDb::Config.stemmer
    parser.stemming_strategy = Xapian::QueryParser::STEM_SOME
    parser.stopper           = XapianDb::Config.stopper
  end

  # Add the searchable prefixes to allow searches by field
  # (like "name:Kogler")
  processors = [] # The reason for having a seemingly useless "processors" array is as follows:
  # We need to add a reference to the generated Xapian::XYValueRangeProcessor objects to the scope that calls parser.parse_query.
  # If we don't, the Ruby GC will often garbage collect the generated objects before parser.parse_query can be called,
  # which would free the memory of the corresponding C++ objects and result in segmentation faults upon calling parse_query.
  XapianDb::DocumentBlueprint.searchable_prefixes.each do |prefix|
    parser.add_prefix(prefix.to_s.downcase, "X#{prefix.to_s.upcase}")
    type_info = XapianDb::DocumentBlueprint.type_info_for(prefix)
    next if type_info.nil? || type_info == :generic
    value_number = XapianDb::DocumentBlueprint.value_number_for(prefix)
    case type_info
      when :date
        processor = Xapian::DateValueRangeProcessor.new(value_number, "#{prefix}:")
        processors << processor
        parser.add_valuerangeprocessor(processor)
      when :number
        processor = Xapian::NumberValueRangeProcessor.new(value_number, "#{prefix}:")
        processors << processor
        parser.add_valuerangeprocessor(processor)
      when :string
        processor = Xapian::StringValueRangeProcessor.new(value_number, "#{prefix}:")
        processors << processor
        parser.add_valuerangeprocessor(processor)
    end
  end
  query = parser.parse_query(expression, @query_flags)
  @spelling_suggestion = parser.get_corrected_query_string.force_encoding("UTF-8")
  @spelling_suggestion = nil if @spelling_suggestion.empty?
  query
end