1

ページのドロップダウンから選択した場合は、ファセットでフィルタリングするだけでなく、2 つのフィールドに対して検索クエリを照合しようとしています。

ユーザーがキーワードを入力すると、タイトルと説明の 2 つのデータベース フィールドに見つかった場合、一致する必要があります。ドロップダウンは、ステータスとタイプでフィルタリングします。

これが私のタイヤ検索構成です。

  def self.search(params)
      tire.search(load: true, page: params[:page], per_page: 25) do
        query do
          boolean do
            should { string "title:#{params[:query]}", default_operator: "OR" } if params[:query].present?
            should { string "description:#{params[:query]}", default_operator: "OR" } if params[:query].present?
            must { term :status_id, params[:status_id] } if params[:status_id].present?
            must { term :type_id, params[:type_id] } if params[:type_id].present?
          end
        end
        sort { by :updated_at, "desc" } if params[:query].blank?
        facet "status" do
          terms :status_id
        end
        facet "type" do
          terms :type_id
        end
      end
  end

インデックス設定:

  settings :analysis => {
      :filter => {
          :my_ngram => {
              "type" => "nGram",
              "max_gram" => 10,
              "min_gram" => 3}
      },
      :analyzer => {
          :my_analyzer => {
              "type" => "custom",
              "tokenizer" => "lowercase",
              "filter" => ["my_ngram"]
          }
      }
  } do
    mapping do
      indexes :title, boost: 10, analyzer: 'my_analyzer'
      indexes :description, boost: 5, analyzer: 'my_analyzer'
      indexes :status_id, :type => 'integer'
      indexes :type_id, :type => 'integer'
    end
  end

私はもともとタイトルと説明のフィールドしか持っていませんでしたが、うまく機能していました。現在、ステータスとタイプでフィルタリングする機能を追加しようとしています。

これを構成する適切な方法は何ですか? ステータスが選択されている場合、そのステータスのレコードのみが返されます。タイプと両方が選択されている場合も同様です。

どんな助けでも大歓迎です。

エラーが発生するわけではありませんが、キーワードまたはファセットによって結果がまったくフィルター処理されなくなります。

curl -X GET 'http://localhost:9200/projects/project/_search?load=true&size=25&pretty' -d '{"query":{"bool":{"should":[{"query_string":{"query":"title:test","default_operator":"OR"}},{"query_string":{"query":"description:test","default_operator":"OR"}}],"must":[{"term":{"status_id":{"term":"1"}}},{"term":{"type_id":{"term":"1"}}}]}},"facets":{"status":{"terms":{"field":"status_id","size":10,"all_terms":false}},"type":{"terms":{"field":"type_id","size":10,"all_terms":false}}},"size":25}'

# 2013-08-16 12:08:34:791 [200] (31 msec)
#
# {"took":31,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]},"facets":{"status":{"_type":"terms","missing":0,"total":0,"other":0,"terms":[]},"type":{"_type":"terms","missing":0,"total":0,"other":0,"terms":[]}}}
4

1 に答える 1

3

これと同等のものを作成できれば、望ましい結果が得られると思います。(JSON キーに引用符がないことをお許しください!)

{
    query: {
      multi_match: {
        query: "test",
        fields: ["title", "description"]
      }
    },
    filter: {
      and: [
        {
          term: { status_id: 123 }
        },
        {
          term: { type_id: 456 }
        }
      ]
    },
    facets: {
      type: {
        terms: {
          field: "type_id",
          size: 10
        }
      },
      status: {
        terms: {
          field: "status_id",
          size: 10
        }
      }
    }
}

アップデート

タイヤはわかりませんが、何か書いてみます!

  def self.search(params)
    tire.search(load: true, page: params[:page], per_page: 25) do
      query do
        boolean do
          should { match :title params[:query] } if params[:query].present?
          should { match :description  params[:query] } if params[:query].present?
        end
      end

      sort { by :updated_at, "desc" } if params[:query].blank?

      filter :and, { :term => { :status_id => params[:status_id] } } if params[:status_id].present?
                   { :term => { :type_id => params[:type_id] } } if params[:type_id].present?
    end
  end

おそらくルビーを修正する必要がありますが、注意すべき点がいくつかあります。一致クエリは、推奨されるデフォルトの文字列検索であり、一致クエリよりも高速ですquery_string(ただし、制御はわずかに劣ります)。また

于 2013-08-17T12:15:57.523 に答える