Class: RDF::Query

Inherits:
Object
  • Object
show all
Defined in:
lib/rdf/query.rb,
lib/rdf/query/pattern.rb,
lib/rdf/query/variable.rb,
lib/rdf/query/solution.rb,
lib/rdf/query/solutions.rb

Overview

An RDF basic graph pattern (BGP) query.

Examples:

Constructing a basic graph pattern query (1)

query = RDF::Query.new do
  pattern [:person, RDF.type,  FOAF.Person]
  pattern [:person, FOAF.name, :name]
  pattern [:person, FOAF.mbox, :email]
end

Constructing a basic graph pattern query (2)

query = RDF::Query.new({
  :person => {
    RDF.type  => FOAF.Person,
    FOAF.name => :name,
    FOAF.mbox => :email,
  }
})

Executing a basic graph pattern query

graph = RDF::Graph.load('etc/doap.nt')
query.execute(graph).each do |solution|
  puts solution.inspect
end

Constructing and executing a query in one go (1)

solutions = RDF::Query.execute(graph) do
  pattern [:person, RDF.type, FOAF.Person]
end

Constructing and executing a query in one go (2)

solutions = RDF::Query.execute(graph, {
  :person => {
    RDF.type => FOAF.Person,
  }
})

Since:

Defined Under Namespace

Classes: Pattern, Solution, Solutions, Variable

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Object) initialize(patterns = [], options = {}) {|query| ... } - (Object) initialize(patterns, options = {}) {|query| ... }

Initializes a new basic graph pattern query.

Overloads:

  • - (Object) initialize(patterns = [], options = {}) {|query| ... }

    Parameters:

    • (Array<RDF::Query::Pattern>) patterns

      ...

    • (Hash{Symbol => Object}) options

      any additional keyword options

    Options Hash (options):

    Yields:

    • (query)

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

  • - (Object) initialize(patterns, options = {}) {|query| ... }

    Parameters:

    • (Hash{Object => Object}) patterns

      ...

    • (Hash{Symbol => Object}) options

      any additional keyword options

    Options Hash (options):

    Yields:

    • (query)

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

Since:

  • 0.3.0



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/rdf/query.rb', line 111

def initialize(patterns = nil, options = {}, &block)
  @options   = options.dup
  @variables = {}
  @solutions = @options.delete(:solutions) || Solutions.new

  @patterns  = case patterns
    when Hash  then compile_hash_patterns(patterns.dup)
    when Array then patterns
    else []
  end

  if block_given?
    case block.arity
      when 0 then instance_eval(&block)
      else block.call(self)
    end
  end
end

Instance Attribute Details

- (Hash) options (readonly)

Any additional options for this query.

Returns:

  • (Hash)

Since:

  • 0.3.0



87
88
89
# File 'lib/rdf/query.rb', line 87

def options
  @options
end

- (Array<RDF::Query::Pattern>) patterns (readonly)

The patterns that constitute this query.

Returns:

Since:

  • 0.3.0



75
76
77
# File 'lib/rdf/query.rb', line 75

def patterns
  @patterns
end

- (RDF::Query::Solutions) solutions (readonly)

The solution sequence for this query.

Returns:

Since:

  • 0.3.0



81
82
83
# File 'lib/rdf/query.rb', line 81

def solutions
  @solutions
end

- (Hash{Symbol => RDF::Query::Variable}) variables (readonly)

The variables used in this query.

Returns:

Since:

  • 0.3.0



69
70
71
# File 'lib/rdf/query.rb', line 69

def variables
  @variables
end

Class Method Details

+ (RDF::Query::Solutions) execute(queryable, patterns = nil, options = {}) {|query| ... }

Executes a query on the given queryable graph or repository.

Parameters:

  • (RDF::Queryable) queryable

    the graph or repository to query

  • (Hash{Object => Object}) patterns (defaults to: nil)

    optional hash patterns to initialize the query with

  • (Hash{Symbol => Object}) options (defaults to: {})

    any additional keyword options (see #initialize)

Yields:

  • (query)

Yield Parameters:

Yield Returns:

  • (void)

    ignored

Returns:

See Also:

Since:

  • 0.3.0



61
62
63
# File 'lib/rdf/query.rb', line 61

def self.execute(queryable, patterns = nil, options = {}, &block)
  self.new(patterns, options, &block).execute(queryable, options)
end

Instance Method Details

- <<(pattern)

This method returns an undefined value.

Appends the given query pattern to this query.

Parameters:

Since:

  • 0.3.0



136
137
138
139
# File 'lib/rdf/query.rb', line 136

def <<(pattern)
  @patterns << Pattern.from(pattern)
  self
end

- (Enumerator) each_solution {|solution| ... } Also known as: each

Enumerates over each matching query solution.

Yields:

  • (solution)

Yield Parameters:

Returns:

Since:

  • 0.3.0



268
269
270
# File 'lib/rdf/query.rb', line 268

def each_solution(&block)
  @solutions.each(&block)
end

- (RDF::Query::Solutions) execute(queryable, options = {})

Executes this query on the given queryable graph or repository.

Parameters:

  • (RDF::Queryable) queryable

    the graph or repository to query

  • (Hash{Symbol => Object}) options (defaults to: {})

    any additional keyword options

Returns:

See Also:

Since:

  • 0.3.0



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/rdf/query.rb', line 193

def execute(queryable, options = {})
  options = options.dup

  # just so we can call #keys below without worrying
  options[:bindings] ||= {}

  @solutions = Solutions.new
  # A quick empty solution simplifies the logic below; no special case for
  # the first pattern
  @solutions << RDF::Query::Solution.new({})

  @patterns.each do |pattern|
    
    old_solutions, @solutions = @solutions, Solutions.new

    options[:bindings].keys.each do |variable|
      if pattern.variables.include?(variable)
        unbound_solutions, old_solutions = old_solutions, Solutions.new
        options[:bindings][variable].each do |binding|
          unbound_solutions.each do |solution|
            old_solutions << solution.merge(variable => binding)
          end
        end
        options[:bindings].delete(variable)
      end
    end

    old_solutions.each do |solution|
      pattern.execute(queryable, solution) do |statement|
        @solutions << solution.merge(pattern.solution(statement))
      end
    end

    # It's important to abort failed queries quickly because later patterns
    # that can have constraints are often broad without them.
    # We have no solutions at all:
    return @solutions if @solutions.empty?
    # We have no solutions for variables we should have solutions for:
    if !pattern.optional? && pattern.variables.keys.any? { |variable| !@solutions.variable_names.include?(variable) }
      return Solutions.new
    end
  end
  @solutions
end

- (Boolean) failed?

Returns true if this query did not match when last executed.

When the solution sequence is empty, this method can be used to determine whether the query failed to match or not.

Returns:

  • (Boolean)

See Also:

Since:

  • 0.3.0



246
247
248
# File 'lib/rdf/query.rb', line 246

def failed?
  @solutions.empty?
end

- (Boolean) matched?

Returns true if this query matched when last executed.

When the solution sequence is empty, this method can be used to determine whether the query matched successfully or not.

Returns:

  • (Boolean)

See Also:

Since:

  • 0.3.0



258
259
260
# File 'lib/rdf/query.rb', line 258

def matched?
  !@failed
end

- (RDF::Query) optimize(options = {})

Returns an optimized copy of this query.

Parameters:

  • (Hash{Symbol => Object}) options (defaults to: {})

    any additional options for optimization

Returns:

Since:

  • 0.3.0



163
164
165
# File 'lib/rdf/query.rb', line 163

def optimize(options = {})
  self.dup.optimize!(options)
end

- optimize!(options = {})

This method returns an undefined value.

Optimizes this query by reordering its constituent triple patterns according to their cost estimates.

Parameters:

  • (Hash{Symbol => Object}) options (defaults to: {})

    any additional options for optimization

See Also:

Since:

  • 0.3.0



176
177
178
179
180
181
# File 'lib/rdf/query.rb', line 176

def optimize!(options = {})
  @patterns.sort! do |a, b|
    (a.cost || 0) <=> (b.cost || 0)
  end
  self
end

- pattern(pattern, options = {})

This method returns an undefined value.

Appends the given query pattern to this query.

Parameters:

  • (RDF::Query::Pattern) pattern

    a triple query pattern

  • (Hash{Symbol => Object}) options (defaults to: {})

    any additional keyword options

Options Hash (options):

  • (Boolean) :optional — default: false

    whether this is an optional pattern

Since:

  • 0.3.0



151
152
153
154
# File 'lib/rdf/query.rb', line 151

def pattern(pattern, options = {})
  @patterns << Pattern.from(pattern, options)
  self
end