Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return Records #1

Open
EasyIP2023 opened this issue Jun 26, 2017 · 7 comments
Open

Return Records #1

EasyIP2023 opened this issue Jun 26, 2017 · 7 comments

Comments

@EasyIP2023
Copy link

EasyIP2023 commented Jun 26, 2017

Hey Instead of returning an array/hash is there a way to return records?
I opened up rails c and played around with it. If you type

u = User.ft_search(keyword: 'rand', offset: 0, num: 10)
GlobalID::Locator.locate u[1]

It returns the record is there any way to implement that into the gem?

My users_controller looks like this

class UsersController < ApplicationController
  include UsersHelper
  def index
    if params[:search]
      search_users
    else
      fetch_users
    end
  end
end

my users_helper method looks something like

module UsersHelper
  def fetch_users
    users =  $redis.get("users")
    if users.nil?
      $redis.pipelined {
        users = User.active.order(:email).to_json
        $redis.set("users", users)
      }
    end
    @users = JSON.load users
  end

  def search_users
    users = User.searchable(params[:search]).to_json
    $redis.set("users", users)
    @users = JSON.load users
  end
end

Users model

class User < ApplicationRecord
  include RediSearchRails
  
  after_save :reload_cache
  redi_search_schema first_name:  'TEXT',
                      last_name:   'TEXT',
                      email:       'TEXT',
                      phone:       'TEXT',
                      address:     'TEXT',
                      city:        'TEXT',
                      state:       'TEXT',
                      country:     'TEXT',
                      postal_code: 'TEXT'
  
 def reload_cache
    $redis.del "users"
    User.ft_add_all
 end

 def self.searchable(search)
   User.ft_search(keyword: "#{search}", offset: 0, num: 10)
 end
end

Simple form in users index view

%h2 Users

= form_tag users_path, method: :get do
  %p
    = text_field_tag :search, params[:search]
    = submit_tag 'Search'

%br
%div{style: "overflow-x:auto;"}
  %table#table.table
    %thead
      %tr
        %th Email
        %th Locked
        %th
    %tbody
      - @users.each do |user|
        %tr
          %td= user["email"]
          %td= user["locked_at?"] ? 'LOCKED' : ''
          %td
            = link_to 'show', user_path(["user"]), class: 'btn btn-success btn-block'
@dmitrypol
Copy link
Owner

Hi Vincent
I apologise for slow response and thank you for submitting such detailed issue report. Just to clarify, you want to return the list of GlobalIDs for the search results. Then you would query the primary data store looking for the actual records which would be returned as objects? Did I understand your issue correctly?
Dmitry

@EasyIP2023
Copy link
Author

Yep!!! Not entirely sure if it's faster to search through cache, return the gid's, and then query out to sql to return the actual records or just use a gem like ransack, but it would be nice.

@dmitrypol
Copy link
Owner

It's an interesting idea when you have LOTS of data. You might simply choose to index the keywords but NOT store the documents (aka DB records) in Redis. You would use NOSAVE http://redisearch.io/Commands/#ftadd for that (I still have to implement support for that in the gem).

I think this will slow down the process as it will then need to query your primary DB (MySQL) for the specific GlobalIDs.

I will think about how to best support this use case and try to implement it. Otherwise PRs are welcomed.

@EasyIP2023
Copy link
Author

EasyIP2023 commented Jun 29, 2017

Hey thanks!!! But nvm this example is exactly what I've wanted to try and implement https://github.com/mrvncaragay/rails-redis-search.

@dmitrypol
Copy link
Owner

I think this example will give you exact matches using regular Redis. But if you install RediSearch module (requires Redis4) that will give you full text search capabilities (if that's what you need).

@EasyIP2023
Copy link
Author

EasyIP2023 commented Jun 29, 2017

Trying to do this in a production env. Completely new to redis I think it's awesome though!!! I just realized, I don't need those records I just need the returned array/hash?.. and to render the views via js.

Excuse me for my ignorance, basically I want to search through redis and render in views via js the returned results so that it appears as if I'm searching through an entire db instantly.

Now is it better to full text search or do exact matches? I don't know!!!!

@dmitrypol
Copy link
Owner

NP, we all start with technologies sometimes.
I can't answer "full text" vs "exact match" question, that's your application logic. But you can do exact match w RediSearch too (http://redisearch.io/Commands/#ftsearch). But if you are just starting with Redis I would not advise on jumping into RediSearch module as it requires running Redis 4 which is still not officially released nor supported by any hosting providers. You would need to install your own Linux server, clone Redis repo, compile it, and the do the same for the module. Despite having done that many times in dev I do not like to do that in prod.
Also feel free to read my blog http://dmitrypol.github.io/categories.html#redis.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants