繁体   English   中英

在ElasticSearch和Tire中使用缺少过滤器的构面

[英]Using facets with missing filters in ElasticSearch and Tire

我正在尝试使用包含缺少筛选器的搜索查询中的方面,并且它似乎没有考虑到将使用缺少筛选器过滤掉的记录。

在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
}'

可以获取构面,但未考虑过滤的记录。

我还有另一种方式可以编写查询,以便我也可以考虑缺少筛选器的方面吗?

如果我理解正确,那么您就会遇到这样的问题,即根据查询(而不是顶级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查询通常是更好的选择。

暂无
暂无

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

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