0

这就是我希望在不使用 gem 的情况下实现的目标。我在我的一个视图中有一个搜索功能,我希望允许人们在单个字段中输入名字和姓氏,让我的类方法搜索名字和姓氏并生成一个列表。我目前有以下丑陋的代码,它将在两个字段上进行全文搜索。怜悯我 :) 我是 SQL 和 PostgreSQL 的新手。我只做了基本的查询。

  def self.text_search(query)
    if query.present?
      q1, q2, q3, q4 = query.split(' ')
      case
      when q4 != nil
        where('first_name @@ :q1 OR first_name @@ :q2 OR first_name @@ :q3 OR first_name @@ :q4 OR last_name @@ :q1 OR last_name @@ :q2 OR last_name @@ :q3 OR last_name @@ :q4', q1: q1, q2: q2, q3: q3, q4: q4)
      when q3 != nil
        where('first_name @@ :q1 OR first_name @@ :q2 OR first_name @@ :q3 OR last_name @@ :q1 OR last_name @@ :q2 OR last_name @@ :q3', q1: q1, q2: q2, q3: q3)
      when q2 != nil
        where('first_name @@ :q1 OR first_name @@ :q2 OR last_name @@ :q1 OR last_name @@ :q2', q1: q1, q2: q2)
      else
        where('first_name @@ :q1 OR last_name @@ :q1', q1: q1)
      end
    else
      scoped
    end
  end

此代码适用于它在两个字段中搜索整个单词并生成所有匹配的记录。但是,我想做的是能够搜索以在搜索框中输入的值开头的列。例如,如果有人输入“Pat”,则查询将选择 Pat、Patrick、Patrice、Patricia 等。我确信有更好的方法来编写我包含的代码,我可以在其中列出我想要的所有值检查 first_name 和 last_name (或者至少我希望有)。

我今天一直在做很多关于这个的网络搜索。我发现了很多关于这方面的各个方面的信息。我看到了如何使用变量创建正则表达式。这对我来说很明显。我的问题是弄清楚如何将这些信息传递到我的 where 子句中。例如,我为所有四个字段尝试了以下代码。

qr1 = /^#{q1}/

然后我做了一个类似的 where 子句,我检查了 first_name 和 last_name 的所有四个值。我的查询没有返回任何行。

where ('first_name ~ :qr1', qr1: qr1)

我还看到了有关检查子字符串与数组进行比较的解决方案。我在该解决方案中看到的问题是,您必须知道输入的值需要多长时间才能成功。这是一个带有示例的 Stack Overflow 帖子:

选择范围内的第一个字母(PostgreSQL)

我还观看了 RailsCasts #343 (Pro),其中讨论了 to_tsvector 和 plainto_tsquery,但坦率地说我迷路了。也许这是我的答案,但我可以肯定需要一些帮助。这对我来说就像泥巴一样清晰。

4

1 回答 1

0
def self.text_search(query)
  if query.present?
    arr = query.split(' ').map { |q| "%#{q}" }

    where('first_name ~~* ANY(ARRAY[:arr]) OR last_name ~~* ANY(ARRAY[:arr])', arr: arr)
  else
    scoped
  end
end
于 2012-12-28T18:40:17.027 回答