【问题标题】:Using facets with missing filters in ElasticSearch and Tire在 ElasticSearch 和 Tire 中使用缺少过滤器的构面
【发布时间】:2016-12-10 15:42:01
【问题描述】:

我正在尝试将构面与包含缺失过滤器的搜索查询一起使用,它似乎没有考虑将被缺失过滤器过滤掉的记录。

在 Rails 应用程序中:

@items = Item.search(per_page: 100, page: params[:page], load: true) do |search|
  search.query do |query|
    query.boolean do |boolean|
      boolean.must { |must| must.string params[:q], default_operator: "AND" }
      boolean.must { |must| must.term :project_id, @project.id }
    end
    query.filtered do
      filter :missing , :field =>  :user_id
    end
  end
  search.facet('tags') do
    terms :tag
  end
end

生成请求:

curl -X GET 'http://localhost:9200/items/user_story/item?load=true&size=100&pretty' -d '{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "*",
            "default_operator": "AND"
          }
        },
        {
          "term": {
            "project_id": {
              "term": 132
            }
          }
        }
      ]
    },
    "filtered": {
      "filter": {
        "and": [
          {
            "missing": {
              "field": "user_id"
            }
          }
        ]
      }
    }
  },
  "facets": {
    "tags": {
      "terms": {
        "field": "tag",
        "size": 10,
        "all_terms": false
      }
    }
  },
  "size": 100
}'

其中有nil 表示构面。

如果我将丢失的过滤器移出到 search.filter

@items = Item.search(per_page: 100, page: params[:page], load: true) do |search|
  search.query do |query|
    query.boolean do |boolean|
      boolean.must { |must| must.string params[:q], default_operator: "AND" }
      boolean.must { |must| must.term :project_id, @project.id }
    end
  end
  search.filter(:missing, :field => 'user_id' )
  search.facet('tags') do
    terms :tag
  end
end

...它发出请求:

curl -X GET 'http://localhost:9200/user_stories/user_story/_search?load=true&size=100&pretty' -d '{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "*",
            "default_operator": "AND"
          }
        },
        {
          "term": {
            "project_id": {
              "term": 132
            }
          }
        }
      ]
    }
  },
  "facets": {
    "tags": {
      "terms": {
        "field": "tag",
        "size": 10,
        "all_terms": false
      }
    }
  },
  "filter": {
    "missing": {
      "field": "user_id"
    }
  },
  "size": 100
}'

确实获得了方面,但它们不考虑过滤的记录。

我是否应该以另一种方式编写查询,以便获得同时考虑到缺失过滤器的方面?

【问题讨论】:

    标签: ruby-on-rails ruby elasticsearch tire


    【解决方案1】:

    如果我理解正确,您遇到的问题是从受查询限制的结果而不是顶级 filter 元素计算方面。此外,第一个查询对我来说看起来不正确。

    我会这样重写请求:

    require 'tire'
    
    params = {:q => 'foo'}
    
    s = Tire.search do |search|
      search.query do |search_query|
        search_query.filtered do |f|
    
          # Queries
          f.query do |q|
            q.string params[:q], default_operator: "AND"
          end
    
          # Filters
          f.filter :missing , :field => :user_id
          f.filter :term,     :project_id => '123'
        end
      end
      search.facet('tags') do
        terms :tag
      end
    end
    
    puts s.to_curl
    

    基本上,我们使用filtered 查询作为主要查询,摆脱布尔查询,并使用filter 以获得最大效率(缺失和术语)。

    当然,如果您需要执行更多查询,您可以使用q.boolean 而不是q.string

    最后,string 查询(即 Lucene 查询字符串查询)通常不是常规搜索的最佳选择,因为它向用户展示了整个“特殊 Lucene 语法”,并且容易出错。 match 查询通常是更好的选择。

    【讨论】:

    • 感谢您的回复。今天晚些时候我会试试这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多