Skip to content
Scott Williams edited this page Jun 13, 2014 · 1 revision

Querying

Arkenstone has a query language based off of Mongo DB's. It can be used to perform complex searches for entities.

How to use the Query DSL

Include the Arkenstone::Queryable module. This gives you access to the where method on your class.

class Widget
  include Arkenstone::Document
  include Arkenstone::Queryable
  
  url 'http://example.com/widgets'
  
  attributes :name, :size, :sku
end

# snip

search_results = Widget.where do
  name: 'ABC'
end

where has a couple different ways to call it. The first is with a DSL that can let you declare boolean logic and other functions (more specifics on this in a bit).

For simple queries, you can send in a hash. It is not recommended to add booleans with this approach.

search_results = Widget.where({name: 'ABC'})

Since all queries are ultimately serialized to JSON, you can provide a raw JSON string as well. You can add complex logic if you are familiar with how the DSL builds a query. This can lead to subtle mistakes at runtime though.

search_results = Widget.where('{"name": "ABC"}')

DSL specifics

The Query DSL gives you flexibility to build complex search queries. Commands can be nested and combined.

_in

Finds the entries that have a value for a column in the provided array.

search_results = Widget.where do
  name: _in(['ABC', 'DEF'])
end

Only find Widgets with a name of 'ABC' or 'DEF'

_gt

Finds entries who's values for a column are greater than the value provided.

search_results = Widget.where do
  size: _gt(100)
end

Only find Widgets with a size greater than 100

_gte, _lt, _lte

Similar functionality as _gt. These perform a greater than or equal, less than, or less than or equal respectively.

_limit

Sets a max number of results to return. Used in conjunction with another query.

search_results = Widget.where do
  _limit 10
  {
    sku: '1000'
  }
end

Get 10 Widgets with a sku of '1000'.

_include

Some entities can have nested resources (like metadata). This adds a directive to the query to include those resources. You can include multiple nested resources.

search_results = Widget.where do
  _include ['Widget_MetaData']
  {
    sku: '1000'
  }
end

Get all widgets with a sku of '1000' and include all the metadata.

Boolean logic

You can perform AND, OR, or NOT logic in queries. Each uses the same syntax, but with a different function name.

search_results = Widget.where do
  _and(
    { name: 'ABC'},
    { sku: '1000' }
  )
end

Get all Widgets with both a name 'ABC' and sku '1000'.

OR queries use _or and NOT queries use _not in the place of _and.

Boolean queries can combine other directives as well.

search_results = Widget.where do
  _or(
    { name: 'ABC'},
    { size: _gt(100) }
  )
end

Get all Widgets with either a name 'ABC' or a size greater than 1000.

In fact, boolean logic can be nested as well.

search_results = Widget.where do
  _or(
    _and(
      { name: 'ABC'},
      { sku: '1000' }
    ),
    { name: 'Mike' }
  )
end

Get all Widgets either named 'Mike' or with both a name 'ABC' and sku '1000'.

Clone this wiki locally