Marelons
Marelons

Reputation: 160

Searching postgresql arrays with searchkick

I have a search functionality that I would like to search by various fields. I am already using multi_search to look for different records from different models.

    @entries_result = Post.search(params[:q].presence || '*',
      fields: ['title^10', 'content', 'rating', 'parent_id', 'tags'],
      ...
      where: { parent_id: @parent.id },
      limit: 3)

    @categories_result = Category.search(params[:q].presence || '*', ...)

    @tags_result = Post.search(params[:q].presence || '*',
      fields: ['tags'],
      match: :word_start,
      highlight: true,
      misspellings: { below: 3 },
      where: { parent_id: @parent.id, tags: params[:q] })

    Searchkick.multi_search([@categories_result, @entries_result, @tags_result])

    @tags_result.map(:&tags)

As you can see I am searching through Post model twice, as I need

  1. Posts with specific name(shown on top of the search results)
  2. Tags which are an Array in psql, that I will be showing on the side of the search results
#  tags :text default([]), is an Array, indexed

I can't figure out how to find these tags that are a result of searching by params[:q]. I know that Elasticsearch can search these arrays in documents, but I couldn't find any info on how to do this with searchkick gem. For example when params[:q] is dog I'd like to search for Posts that start with the keyword dog and also tags that start with keyword dog.

Rails 7, gems opensearch (2.0.0), searchkick (5.0.3)

Upvotes: 0

Views: 309

Answers (1)

Marelons
Marelons

Reputation: 160

I ended up building an advanced query as it's also possible to just use elasticsearch/opensearch queries in searchkick, and below code works fine for me.

    @tags_result = Post.search(body:
      { query: {
        bool: {
          should: [
            prefix: {
              tags: params[:q].presence || '*',
            },
          ],
          filter: {
            term: {
              parent_id: @parent.id,
            },
          },
        },
      } })

Upvotes: 0

Related Questions