【问题标题】:Facet Troubles with Elasticsearch on Query查询上的 Elasticsearch 方面的问题
【发布时间】:2012-04-11 08:41:47
【问题描述】:

向我的查询而不是过滤器添加术语时,我得到 0 个方面。仅供参考,我正在将轮胎宝石与 Ruby 一起使用。

这是我的模型代码及其映射:

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

那么这里是搜索方法

  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

我得到 0 个方面。 但如果我将构面移至过滤器,即在下方,我会得到完整的构面。

  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

虽然这没关系,但它不需要,当单击构面过滤器时,我想从我的构面过滤器中删除不可用的标签并更新新的构面计数。

如果这里有帮助,那就是查询的 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
}

真的希望有人可以建议。开始把我的头发拉出来了。

【问题讨论】:

  • 只是为了确定,没有分面的查询是否返回任何结果?
  • 如果我注释掉标签的术语过滤器,那么它会返回结果。我确实得到了方面。所以对我来说,术语方面查询是一个错误?
  • 我的意思是,如果你不注释掉“must { term 'tags.name.exact', params[:tag]}”,你会得到任何搜索结果(不是方面)。分面是根据请求的查询部分限制的结果计算的。因此,如果查询未返回任何结果,则不会得到任何构面。
  • 好的。如果我把术语标签留在里面,那么我不会得到任何结果。

标签: ruby-on-rails ruby elasticsearch tire


【解决方案1】:

您应该使用过滤查询进行构面搜索以获得准确的结果:

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

【讨论】:

    【解决方案2】:

    我实际上非常接近。由于我的标签可以有多个我需要使用术语而不是术语 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
    

    感谢 imotov,Hoang 的建议。

    【讨论】:

      【解决方案3】:

      搜索请求通常由两部分组成:查询和过滤器。如果搜索请求仅包含查询部分,则根据完整的搜索结果计算分面。换言之,如果搜索结果包含 10 条带有“Pet Friendly”标签的记录和 5 条带有“No Pets Allowed”标签的记录,则构面响应将包含两个构面:“Pet Friendly”和“No Pets Allowed”。现在让我们假设用户通过选择“宠物友好”标签来限制结果。如果在请求的查询部分添加“Pet Friendly”子句,则搜索结果将限制为10条带有“Pet Friendly”标签的记录,并且只返回一个方面:“Pet Friendly”。但是,如果添加“Pet Friendly”子句作为过滤器,搜索结果仍将限制为 10 条记录,但会返回两个方面。之所以会发生这种情况,是因为构面仅根据搜索请求的查询部分计算,而查询部分并未更改 - 它仍然会生成包含 15 条记录的搜索结果,其中包含两个不同的构面。

      要回答您的问题,如果查询未返回任何结果(例如,用户同时选择了“Pet Friendly”和“No Pets Allowed”标签),则结果中没有任何方面,因此不会返回任何方面。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-21
        • 1970-01-01
        • 2014-03-11
        • 2019-10-03
        • 2012-04-17
        • 2019-09-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多