简体   繁体   English

在查询上使用Elasticsearch进行方面的麻烦

[英]Facet Troubles with Elasticsearch on Query

When adding a term to my query instead of a filter I am getting 0 facets. 在我的查询中添加一个术语而不是过滤器时,我得到了0个方面。 FYI I am using the tire gem with Ruby. 仅供参考我正在使用Ruby的轮胎宝石。

Here is my model code with its mapping: 这是我的模型代码及其映射:

class Property < ActiveRecord::Base
  include Tire::Model::Search
  include Tire::Model::Callbacks

  has_and_belongs_to_many :tags

   mapping do
    indexes :id,                type: 'integer'
    indexes :status
    indexes :refno,             type: 'integer'
    indexes :name,              :analyzer => 'snowball', :boost => 100
    indexes :description
    indexes :tags,              type: 'object',
                                  properties: {
                                    name: { type: 'multi_field',
                                      fields: {
                                        name: { type: 'string', analyzer: 'snowball' },
                                        exact: { type: 'string', index: 'not_analyzed' }
                                      }
                                    }
                                   }                                 
  end

  def to_indexed_json
    to_json( include: { 
      tags: { only: [:name] },
     })
  end

Then here is the search method 那么这是搜索方法

  def self.search(params={})
    tire.search(page: params[:page], per_page: 2, load: true) do
      query do
        boolean do
         must { string params[:name], default_operator: "AND" } if params[:name].present?
         must { term :status, 'live' }
         must { term :refno, params[:refno]} if params[:refno].present?
         # must { term :tag, params[:tag]} if params[:tag].present? ## does not work either
         must { term 'tags.name.exact', params[:tag]} if params[:tag].present?
        end
      end
      facet "tags" do
        terms 'tags.name.exact'
      end
      raise to_json
      # raise to_curl
    end
  end

I get 0 Facets. 我得到0分面。 But if I move facets to a filter ie below I get full facets. 但是,如果我将小平面移动到过滤器,即下方,我会得到完整的方面。

  def self.search(params={})
    tire.search(page: params[:page], per_page: 2, load: true) do
      query do
        boolean do
         must { string params[:name], default_operator: "AND" } if params[:name].present?
         must { term :status, 'live' }
         must { term :refno, params[:refno]} if params[:refno].present?
        end
      end
      filter :term, 'tags.name.exact' => params[:tag] if params[:tag].present?
      facet "tags" do
        terms 'tags.name.exact'
      end
      raise to_json
      # raise to_curl
    end
  end

While this is ok it's not want, When a facet filter is clicked I want to remove non available tags from my facet filter and update the new facet count. 虽然这没关系,但是不需要,当点击构面过滤器时,我想从我的构面过滤器中删除不可用的标签并更新新的构面计数。

If it helps here is the json for the query which works and does not. 如果它有帮助,那么查询的json有效,有效。

## No Factes
{
   "query":{
      "bool":{
         "must":[
            {
               "query_string":{
                  "query":"England",
                  "default_operator":"AND"
               }
            },
            {
               "term":{
                  "status":"live"
               }
            },
            {
               "term":{
                  "tags.name.exact":[
                     "Pet Friendly"
                  ]
               }
            }
         ]
      }
   },
   "facets":{
      "tags":{
         "terms":{
            "field":"tags.name.exact",
            "size":10,
            "all_terms":false
         }
      }
   },
   "size":2
}

## Facets working
{
   "query":{
      "bool":{
         "must":[
            {
               "query_string":{
                  "query":"England",
                  "default_operator":"AND"
               }
            },
            {
               "term":{
                  "status":"live"
               }
            }
         ]
      }
   },
   "facets":{
      "tags":{
         "terms":{
            "field":"tags.name.exact",
            "size":10,
            "all_terms":false
         }
      }
   },
   "filter":{
      "term":{
         "tags.name.exact":[
            "Pet Friendly"
         ]
      }
   },
   "size":2
}

Really hope someone can advise. 真的希望有人可以提供建议。 Starting to pull my hair out on this one. 开始把这头发拉出来。

You should use filtered query for facet seach to get exact result: 您应该使用筛选查询进行构面搜索以获得准确的结果:

query do          
  filtered do
     query { <search keywords> }
     filter <your filter> (pass in facet values)
  end
end
<facet>
...
<facet>

I was actually very close. 我其实很亲密。 As my tags can have multiple I needed to use terms not term ie, 因为我的标签可以有多个我需要使用术语而不是术语,即,

  def self.search(params={})
    tire.search(page: params[:page], per_page: 2, load: true) do
      query do
        boolean do
         must { string params[:name], default_operator: "AND" } if 
         must { term :status, 'live' }
         must { term :refno, params[:refno]} if params[:refno].present?
         must { terms 'tags.name.exact', params[:tag]} if params[:tag].present?
        end
      end
      facet "tags" do
        terms 'tags.name.exact'
      end
      # raise to_json
      # raise to_curl
    end
  end

Thank you for your advise though imotov, Hoang. 谢谢你的建议虽然imotov,Hoang。

A search request usually consists of two parts: a query and a filter. 搜索请求通常由两部分组成:查询和过滤器。 If a search request contains only a query part, facets are calculated based on the complete search result. 如果搜索请求仅包含查询部分,则基于完整的搜索结果计算构面。 In other words if a search result contains 10 records with the tag "Pet Friendly" and 5 records with the tag "No Pets Allowed", the facet response will contain two facets: "Pet Friendly" and "No Pets Allowed". 换句话说,如果搜索结果包含10个标记为“Pet Friendly”的记录和5个标记为“No Pets Allowed”的记录,则facet响应将包含两个方面:“Pet Friendly”和“No Pets Allowed”。 Now let's assume a user limits results by selecting the "Pet Friendly" tag. 现在让我们假设用户通过选择“Pet Friendly”标签来限制结果。 If the "Pet Friendly" clause is added to the query part of the request, the search result will be limited to 10 records with the "Pet Friendly" tag, and only one facet will be returned: "Pet Friendly". 如果将“Pet Friendly”子句添加到请求的查询部分,则搜索结果将限制为带有“Pet Friendly”标记的10条记录,并且只返回一个方面:“Pet Friendly”。 However, if the "Pet Friendly" clause is added as a filter, the search result will be still limited to 10 records, but two facets will be returned. 但是,如果将“Pet Friendly”子句添加为过滤器,则搜索结果仍将限制为10条记录,但将返回两个方面。 It happens because facets are calculated based only on the query portion of the search request and query portion didn't change - it still produces search results with 15 records with two different facets. 之所以会发生这种情况,是因为构面只是根据搜索请求的查询部分计算而且查询部分没有改变 - 它仍然会生成包含15个记录和两个不同构面的搜索结果。

To answer your question, if a query returns no results (for example, user selected both "Pet Friendly" and "No Pets Allowed" tags) then results have no facets in them, so no facets are returned. 要回答您的问题,如果查询未返回任何结果(例如,用户同时选择了“Pet Friendly”和“No Pets Allowed”标签),则结果中没有任何方面,因此不会返回任何方面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM