太阳黑子搜索排序

发布于 2024-12-29 18:44:27 字数 636 浏览 3 评论 0原文

我将 Sunspot (https://github.com/sunspot/sunspot) 与 Rails 一起使用。

这是我的模型:

class Item < ActiveRecord::Base
  searchable do
    boolean :red
    boolean :blue
    boolean :green
    ...
  end
end

考虑以下搜索:

Item.search
  any_of do
    with :red, true
    with :blue, true
    with :green, true
  end
end

如何对结果进行排序:包含所有颜色的项目,后跟包含 2 种颜色的项目,后跟包含 1 种颜色的项目?

注意:这只是一个搜索示例。答案应该考虑颜色的所有可能的搜索组合。

更新 1

按颜色数量排序将不起作用。例如,假设您有以下项目:

  1. 绿色/蓝色
  2. 绿色/红色/黑色

如果您搜索绿色和蓝色,则项目 2 将出现在项目 1 之前。

I'm using Sunspot (https://github.com/sunspot/sunspot) with Rails.

Here's my model:

class Item < ActiveRecord::Base
  searchable do
    boolean :red
    boolean :blue
    boolean :green
    ...
  end
end

Consider the following search:

Item.search
  any_of do
    with :red, true
    with :blue, true
    with :green, true
  end
end

How can I order the results like this: items containing all of the colors followed by items containing 2 of the colors followed by items containing 1 of the colors?

Note: This is just one example search. The answer should consider all possible search combinations for the colors.

Update 1

Ordering by number of colors won't work. For example, say you have the items:

  1. green/blue
  2. green/red/black

If you search for green and blue, item 2 will come before item 1.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

轻拂→两袖风尘 2025-01-05 18:44:27

丑陋,但可能会解决问题:

class Item < ActiveRecord::Base
  searchable do
    boolean :red
    boolean :blue
    boolean :green
    integer :number_of_colors, :stored => true
  end

  def number_of_colors
    # implementation may vary
    count=0
    self.attributes.each do |k,v|
      if %w(red blue green).include?(k.to_s) && v?
        count += 1
      end
    end
    count
  end
end

然后,重新索引后:

Item.search
  any_of do
    with :red, true
    with :blue, true
    with :green, true
    order_by :number_of_colors, :desc
  end
end

希望这会有所帮助。

Ugly, but would probably do the trick:

class Item < ActiveRecord::Base
  searchable do
    boolean :red
    boolean :blue
    boolean :green
    integer :number_of_colors, :stored => true
  end

  def number_of_colors
    # implementation may vary
    count=0
    self.attributes.each do |k,v|
      if %w(red blue green).include?(k.to_s) && v?
        count += 1
      end
    end
    count
  end
end

Then, after re-indexing:

Item.search
  any_of do
    with :red, true
    with :blue, true
    with :green, true
    order_by :number_of_colors, :desc
  end
end

Hopefully, this helps.

柠栀 2025-01-05 18:44:27

哦!我不认为还有其他颜色在起作用......感谢您的更新。在这种情况下,另一种选择是将对象的所有颜色代码(名称)折叠到可搜索块的一个 text 字段中,然后在该字段上运行全文搜索,使用所有内容所需的颜色作为关键字。获得更多匹配的对象将获得最高的相关性分数,并且将首先返回。类似这样的:

class Item < ActiveRecord::Base
  searchable do
    text :color_codes, :stored => true
  end

  # will return "green blue " for item1 above
  # will return "green red black " for item2 above
  def color_codes
    # implementation may vary
    colors=""
    self.attributes.each do |k,v|
      if %w(red blue green black ...).include?(k.to_s) && v?
        colors += "#{k} "
      end
    end
    colors
  end
end

然后,您的搜索例程将如下所示:

q = "green blue"
Item.search do
  keywords q do
    fields :color_codes
  end
end

当在“绿蓝色”上搜索时,上面的 item1 将获得完全匹配,并且将首先出现。

Oh! I didn't think that there where other colors at play... Thanks for the update. In this case, another option would be to collapse all of the object's color codes (names) in one text field in the searchable block, and then run a full-text search on on that field, using all of the needed colors as keyword. Object that would get more matches would get highest relevancy score, and would be returned first. Something like:

class Item < ActiveRecord::Base
  searchable do
    text :color_codes, :stored => true
  end

  # will return "green blue " for item1 above
  # will return "green red black " for item2 above
  def color_codes
    # implementation may vary
    colors=""
    self.attributes.each do |k,v|
      if %w(red blue green black ...).include?(k.to_s) && v?
        colors += "#{k} "
      end
    end
    colors
  end
end

Then, your search routine would look like:

q = "green blue"
Item.search do
  keywords q do
    fields :color_codes
  end
end

item1 above would get exact match when searched on "green blue", and will come up first.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文