如何在elasticsearch中结合3个术语?

时间:2017-03-16 11:28:59

标签: ruby elasticsearch elasticsearch-dsl

我的搜索需要在用户上组合三个不同的术语:

user_locked? || (user_expired? && !user_granted?)

这就是我现在所得到的,但它会抛出一条错误消息:

query do
  bool do
    must { match_all {} }
    filter do
      bool do
        should { term(user_locked: true) }
        minimum_should_match { 1 }
      end
      bool do
        filter do
          term(user_expired: true)
          term(user_granted: false)
        end
      end
    end
  end
end

错误消息:

NoMethodError: undefined method 'filter' for #<Elasticsearch::DSL::Search::Filters::Bool

任何想法如何解决这个问题,甚至可能是更好的查询?

2 个答案:

答案 0 :(得分:1)

试试这样:

query do
  bool do
    minimum_should_match 1
    should do
      term(user_locked: true)
    end
    should do
      bool do
        must do
          term(user_expired: true)
        end
        must do
          term(user_granted: false)
        end
      end
    end
  end
end

<强>更新

根据你的第二条评论,我们需要否定你的情况,即

!(user_locked? || (user_expired? && !user_granted?))

现在相当于

!user_locked? && (!user_expired? || user_granted?)

转换为

query do
  bool do
    must do
      term(user_locked: false)
    end
    must do
      bool do
        minimum_should_match 1
        should do
          term(user_expired: false)
        end
        should do
          term(user_granted: true)
        end
      end
    end
  end
end

该查询现在将按预期返回user_locked: false, user_expired: false的文档

答案 1 :(得分:0)

我在弹性搜索中使用chewy gem,但您可以根据DSL进行调整。我没有测试过,但我认为它应该可以工作:

   index.query(
     bool: {
       must: { match_all: {} },
         filter: {
           bool: {
             should: [
               {term: { user_locked: false}},
               bool: {
                 must: [
                   { term: { user_expired: false} },
                   { term: { user_granted: true } }
                 ]
                },
              minimum_should_match: 1
              ]
            }
          }
       }
     )