self.search

in elasticsearch-rails/lib/rails/templates/searchable.dsl.rb [89:232]


    def self.search(q, options={})
      @search_definition = Elasticsearch::DSL::Search.search do
        query do

          
          
          unless q.blank?
            bool do

              
              
              should do
                multi_match do
                  query    q
                  fields   ['title^10', 'abstract^2', 'content']
                  operator 'and'
                end
              end

              
              
              if q.present? && options[:comments]
                should do
                  nested do
                    path :comments
                    query do
                      multi_match do
                        query q
                        fields   'comments.body'
                        operator 'and'
                      end
                    end
                  end
                end
              end
            end

          
          else
            match_all
          end
        end

        
        
        post_filter do
          bool do
            must { term categories: options[:category] } if options[:category]
            must { match_all } if options.keys.none? { |k| [:c, :a, :w].include? k }
            must { term 'authors.full_name.raw' => options[:author] } if options[:author]
            must { range published_on: { gte: options[:published_week], lte: "#{options[:published_week]}||+1w" } } if options[:published_week]
          end
        end

        
        
        aggregation :categories do
          
          
          f = Elasticsearch::DSL::Search::Filters::Bool.new
          f.must { match_all }
          f.must { term 'authors.full_name.raw' => options[:author] } if options[:author]
          f.must { range published_on: { gte: options[:published_week], lte: "#{options[:published_week]}||+1w" } } if options[:published_week]

          filter f.to_hash do
            aggregation :categories do
              terms field: 'categories'
            end
          end
        end

        
        
        aggregation :authors do
          
          
          f = Elasticsearch::DSL::Search::Filters::Bool.new
          f.must { match_all }
          f.must { term categories: options[:category] } if options[:category]
          f.must { range published_on: { gte: options[:published_week], lte: "#{options[:published_week]}||+1w" } } if options[:published_week]

          filter f do
            aggregation :authors do
              terms field: 'authors.full_name.raw'
            end
          end
        end

        
        
        aggregation :published do
          
          
          f = Elasticsearch::DSL::Search::Filters::Bool.new
          f.must { match_all }
          f.must { term 'authors.full_name.raw' => options[:author] } if options[:author]
          f.must { term categories: options[:category] } if options[:category]

          filter f do
            aggregation :published do
              date_histogram do
                field    'published_on'
                interval 'week'
              end
            end
          end
        end

        
        
        highlight do
          fields title:    { number_of_fragments: 0 },
                 abstract: { number_of_fragments: 0 },
                 content:  { fragment_size: 50 }

          field  'comments.body', fragment_size: 50 if q.present? && options[:comments]

          pre_tags  '<em class="label label-highlight">'
          post_tags '</em>'
        end

        case
          
          
          when options[:sort]
            sort options[:sort].to_sym => 'desc'
            track_scores true
          
          
          
          when q.blank?
            sort published_on: 'desc'
        end

        
        unless q.blank?
          suggest :suggest_title, text: q, term: { field: 'title.tokenized', suggest_mode: 'always' }
          suggest :suggest_body,  text: q, term: { field: 'content.tokenized', suggest_mode: 'always' }
        end
      end

      __elasticsearch__.search(@search_definition)
    end