ruby-on-rails - 使用 ILIKE 查询时的 PostgreSQL 优先级

标签 ruby-on-rails ruby postgresql

两个固定装置:

one:
  firstname: John
  lastname: Doe
  user_id: 1

two:
  firstname: Jane
  lastname: Doe
  user_id: 1

在我的单元测试中,我有以下内容:

 test "Searching for a contact gets the right person" do
    search = Contact.search("John")
    assert_equal 1, search.count

    search = Contact.search("Doe")
    assert_equal 2, search.count

    search = Contact.search("John Doe")
    assert_equal 1, search.count

    search = Contact.search("John ")
    assert_equal 1, search.count

    search = Contact.search("Doe John")
    assert_equal 1, search.count
  end

...最后是我的模型,它调用搜索方法如下所示:

  def self.search(search)
    # Check if the search query has more than one word
    search_split = search.split(" ")
    if search_split.count > 1
      # User must be searching for a first and last name
      first_word = '%' + search_split[0] + '%'
      second_word = '%' + search_split[1] + '%'
      conditions = "
        firstname ILIKE ? OR lastname ILIKE ? 
        AND 
        firstname ILIKE ? OR lastname ILIKE ?", 
        first_word, first_word, second_word, second_word
      where(conditions)
    else
      # Just searching for a first OR last name
      # Strip any whitespace
      str = search_split[0]
      query = '%' + str + '%'
      conditions = "firstname ILIKE ? OR lastname ILIKE ?", query, query
      where(conditions)
    end
  end

除了对“John Doe”进行测试的测试之外,所有测试都通过了。它实际上最终也拉动了“Jane Doe”。

我认为在相邻的 AND 之前调用两个 OR 存在某种优先级问题,但这对我要完成的事情有意义吗?

我还没有到重构的地步;只是想变绿,这样我才能前进。提前感谢您的帮助!

最佳答案

您需要进行一些重组才能获得您所追求的逻辑:

conditions = "
  (firstname ILIKE ? AND lastname ILIKE ?)
  OR
  (firstname ILIKE ? AND lastname ILIKE ?)",
  first_word, second_word, second_word, first_word

当您调用时,它应该同时匹配“John Doe”和“Doe John”,但不匹配“Jane Doe”:

Contact.search('Jo Do')

您实际上不需要括号,因为 AND has a higher precedence than OR在 bool 代数中(SQL 的逻辑是 based on Boolean Algebra ),但没有充分的理由不包括它们。

关于ruby-on-rails - 使用 ILIKE 查询时的 PostgreSQL 优先级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6886800/

相关文章:

node.js - Sequelize nodejs 返回平面 JSON

database - Postgres 动态创建序列

c# - Npgsql.PostgresException (0x80004005) : 42883: operator does not exist: jsonb #> text

ruby-on-rails - Rails Assets -保留许可证注释

ruby-on-rails - 设计 AJAX - POST 请求 : current_user is null

css - Rails - @import 和 *= require 之间的区别?

ruby-on-rails - 显示哈希列表的快捷方式 "nicely"

Ruby - 覆盖 def 方法

ruby-on-rails - 迁移不回滚

ruby-on-rails - "Like", "Dislike" rails 插件