1

對於我的Rails應用程序,我試圖使用Searckick(elasticsearch)設置高級搜索。他們想要做的事情是:使用searchkick設置高級搜索,應對與多個模型(Rails)的關聯

  • 可以在用戶,位置和能力上進行搜索,並始終將用戶配置文件恢復爲結果。

到目前爲止我已經修復了它,我可以在用戶上搜索,但我不確定如何能夠搜索這些其他模型。

我的路線:

Rails.application.routes.draw do 
    ActiveAdmin.routes(self) 
    devise_for :users, controllers: {sessions: "sessions", registrations:  
    "registrations"} 
    # For details on the DSL available within this file, see 
    http://guides.rubyonrails.org/routing.html 

    root 'pages#home' 

    get "/news", to: 'pages#news' 

    get "welcome_back", to: 'pages#welcome_back' 

    get "/profile", to: "profile#show" 

    resources :profiles do 
    collection do 
     get :autocomplete 
    end 
    end 

    namespace :profile do 
    resources :locations 
    resources :positions 
    resources :competences 
    end 
end 

一個用戶屬於一個位置,必須通過一個連接表多種才能。換句話說:用戶有一個location_id,您可以調用用戶的.competences,以查看用戶擁有哪些users_competences。

任何人都可以告訴我如何設置此搜索?

我的配置控制器:

class ProfilesController < ApplicationController 

    def index 
    query = params[:search].presence || "*" 
    @users = User.search(query, suggest: true, operator: "or") 
    end 

    def autocomplete 
    render json: ["Test"] 
    end 

end 

我試圖在我的模型高清自我(搜索)的工作,但是這是行不通的。

我試了一下:

def self.search(search) 
     where(["User.first_name LIKE ?","%#{search}%"]) 
     where(["User.last_name LIKE ?","%#{search}%"]) 
     where(["User.competences.collect{&:name} IN ?","%#{search}%"]) 
     joins(:location).where("location.name LIKE ?", "%#{search}%") 
    else 
     all 
    end 
    end 

回答

1

TL; DR定義search_data方法來定製您的搜索索引

self.search如當前在你的代碼中定義是不正確self.search方法是一種通過ActiveRecord進行搜索的方法以及您正在使用的任何數據庫。這不是你通過Searchkick搜索的方式。

對於Searchkick如果你想返回用戶屬性,能力相匹配的搜索用戶配置文件和位置,那麼你應該定義的用戶屬性,能力,而且要使用search_data方法通過自定義映射到搜索位置,記錄here

class User < ActiveRecord::Base 
    searchkick locations: ["location"] 
    # this line will eager load your assocations 
    scope :search_import, -> { includes(:location, :competences) } 

    def search_data 
    { 
     first_name: first_name, 
     last_name: last_name, 
     competences: competences.map(&:name), 
     # from your code above it looks like you want to search location.name 
     location_name: location.name 
     # the following merged hash would allow you to search by location latitude and 
     # longitude coordinates if you have them 
     ## if you don't use latitude and longitude then you don't need to include 
     ## `locations: ["location"] when you call searchkick in the User model on line 2 
     ## above or the merged location hash below 
    }.merge(location: {lat: location.latitude, lon: location.longitude}) 
    end 
end 

現在在Profiles#index動作搜索查詢將工作:

@users = User.search(query, suggest: true, operator: "or") 

不需要您定義的self.search方法。

其他注意事項

  • 我假設,因爲你包括在您查詢您正確的用戶模型中定義的建議suggest: true

    class User < ActiveRecord::Base 
        searchkick locations: ["location"], suggest: [:first_name, :last_name, :location_name] # or whatever fields you want 
    end 
    
  • 確保reindex
  • 因爲你只想返回User對象,那麼你不需要索引LocationCompetence型號(從您的代碼上面我不知道您是否以前做過)