Skip to content

Parser of a simple search query language, which produces PostgreSQL ts_vector queries (Ruby)

License

MIT, MIT licenses found

Licenses found

MIT
LICENSE
MIT
LICENSE.txt
Notifications You must be signed in to change notification settings

EugZol/search_query_parser

Repository files navigation

Search Query Parser

This gem allows you to create PostgreSQL 9.6 compatible ts_query expressions from simple-to-use "query language".

See for reference:

Example:

require 'search_query_parser'

q = SearchQueryParser.to_ts_query("
    (cats | !(angry dogs)) &
    (кошки | !(злые собаки))
")
puts q
# ((to_tsquery('cats:*') || (!! (to_tsquery('angry:*') <-> to_tsquery('dogs:*')))) && (to_tsquery('кошки:*') || (!! (to_tsquery('злые:*') <-> to_tsquery('собаки:*')))))

You can use &, |, ! operators in the source query, which are transformed into corresponding PostgreSQL operators. Spaces are transformed into <-> ("follows") PostgreSQL operator.

.to_ts_query accepts 3 arguments, only first is required:

  • Search string
  • Language ('enlgish' by default, will be given as first argument to Postgres' to_tsquery)
  • Whether to use prefix (true by default, :* will be added to each word)

What's the problem

When you use PostgreSQL full-text search you want your users to be able to utilize full power of expressions in a convinient manner. Let's say, you want your users to be able to issue a request to find all documents with cats but without dogs.

Unfortunately, you can't use Postgres' plain_tosquery (link) function for that, which would be the closest match to our goal. If you give the string cates & !dogs to plainto_tsquery, the result will be:

=> select plainto_tsquery('cats & !dogs');
 plainto_tsquery
-----------------
 'cat' & 'dog'

...so, it just drops all the punctuation and concatenate words with logical AND (&), just as the documentation says.

The solution

Use SearchQueryParser.to_ts_query(q) to produce PostgreSQL-compatible expression. All non-alphanumeric and non-operator symbols will be dropped from the q.

How can I use it?

Use it in your Rails finders for models with tsdata columns like that:

q = SearchQueryParser.to_ts_query('кошки & !собаки', 'russian')
Document.where("tsdata @@ #{q}")

Installation

Add this line to your application's Gemfile:

gem 'search_query_parser'

And then execute:

$ bundle

Or install it yourself as:

$ gem install search_query_parser

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/EugZol/search_query_parser.

License

The gem is available as open source under the terms of the MIT License.

About

Parser of a simple search query language, which produces PostgreSQL ts_vector queries (Ruby)

Resources

License

MIT, MIT licenses found

Licenses found

MIT
LICENSE
MIT
LICENSE.txt

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published