我的Rails应用程序中的搜索功能出现问题。我正在将pg_search与Postgresql一起使用,并将波兰字典加载到其中。我做了#343 RailsCasts教程,当我使用默认的search()
方法(性能非常慢)时,一切都很好,但是当通过教程SQL查询中的建议进行优化时,它不能正常工作 - 不会抛出任何错误,只是不使用字典。例如,用短语" herbata owoc"它找到了所有非常合适的记录,尽管与默认记录不一样"搜索"方法,但通过适当的短语,这是" herbata owocowa"当"搜索"它没有找到任何东西。方法返回准确的记录。
当然我做了添加索引的迁移。此外,我尝试了一些触发器等解决方案(http://railscasts.com/episodes/343-full-text-search-in-postgresql?view=comments),但它没有帮助。我使用Ruby on Rails 4.0.5,PostgreSQL 9.1.13,pg_Search 0.7.6。
控制器中的方法调用:
Product.text_search(params[:query])
Model" Product":
include PgSearch
pg_search_scope :text_search, against: [:title, :description],
using: {tsearch: {dictionary: "polish"}}
def self.text_search(query)
if query.present?
# search(query)
rank = <<-RANK
ts_rank(to_tsvector(products.title), plainto_tsquery(#{sanitize(query)})) + ts_rank(to_tsvector(products.description), plainto_tsquery(#{sanitize(query)}))
RANK
where("to_tsvector('polish', products.title) @@ :q or to_tsvector('polish', products.description) @@ :q", q: query.split(" ").join(" & ")).order("#{rank} DESC")
else
scoped
end
end
迁移:
class AddSearchIndexToProducts < ActiveRecord::Migration
def up
execute "create index products_title on products using gin(to_tsvector('polish', title))"
execute "create index products_description on products using gin(to_tsvector('polish', description))"
end
def down
execute "drop index products_title"
execute "drop index products_description"
end
end
我的查询没有结果:
Product Load (1.2ms)
SELECT "products".*
FROM "products"
INNER JOIN "categories" ON "categories"."id" = "products"."category_id"
WHERE
"products"."active" = 't'
AND "categories"."active" = 't'
AND (to_tsvector('polish', products.title) @@ 'herbata & owocowa'
OR to_tsvector('polish', products.description) @@ 'herbata & owocowa')
AND (1=1)
ORDER BY
title,
ts_rank(to_tsvector(products.title), plainto_tsquery('herbata owocowa'))
+ ts_rank(to_tsvector(products.description), plainto_tsquery('herbata owocowa'))
DESC
search()
查询给出了预期的结果,但速度很慢:
Product Load (15391.1ms)
SELECT "products".*, ((ts_rank((to_tsvector('polish', coalesce("products"."title"::text, '')) || to_tsvector('polish', coalesce("products"."description"::text, ''))), (to_tsquery('polish', ''' ' || 'herbata' || ' ''') && to_tsquery('polish', ''' ' || 'owocowa' || ' ''')), 0))) AS pg_search_rank
FROM "products"
INNER JOIN "categories" ON "categories"."id" = "products"."category_id"
WHERE
"products"."active" = 't'
AND "categories"."active" = 't'
AND (
((to_tsvector('polish', coalesce("products"."title"::text, '')) || to_tsvector('polish', coalesce("products"."description"::text, '')))
@@ (to_tsquery('polish', ''' ' || 'herbata' || ' ''')
&& to_tsquery('polish', ''' ' || 'owocowa' || ' ''')))
)
AND (1=1)
ORDER BY
title, pg_search_rank DESC, "products"."id" ASC
我尝试写类似search()
给出的选择,但我失败了。
示例数据:
(1例)
默认搜索()方法,短语:&#34; herbata owocowa&#34;,预计前5个结果:
[[0] #<Product:0x000000083fa3d8> {
:title => "BIOFIX Herbata Kompozycja Owocowa 60 szt",
:description => "Propozycja od dobrze znanej i cenionej polskiej marki Biofix. Doskonała herbata owocowa, która zadowoli wszystkich miłośników bogatego smaku. Idealna propozycja na każdą porę dnia. Doskonale smakuje z miodem lub dodatkiem plastrów cytryny. Zapraszamy do zapoznania się z produktami z pozostałych kategorii. Zrób już dzisiaj zakupy przez internet, a nasze delikatesy chętnie dostarczą Ci smaczną paczkę."
},
[1] #<Product:0x000000083fa040> {
:title => "BIOFIX Herbata Premium Hawaii Dream 20 szt",
:description => "Propozycja od dobrze znanej i cenionej polskiej marki Biofix. Doskonała herbata owocowa, która zadowoli wszystkich miłośników bogatego smaku. Idealna propozycja na każdą porę dnia. Doskonale smakuje z miodem lub dodatkiem plastrów cytryny. Zapraszamy do zapoznania się z produktami z pozostałych kategorii. Zrób już dzisiaj zakupy przez internet, a nasze delikatesy chętnie dostarczą Ci smaczną paczkę."
},
[2] #<Product:0x000000083f9c80> {
:title => "BOBOVITA Herbata dla dzieci cytrynowa 200 g",
:description => "Herbatka owocowa Bobovita to łagodny napój dla niemowląt. Ma delikatny aromat i przyjemny smak, dzięki czemu jej picie jest prawdziwą przyjemnością. W chłodne dni przynosi uczucie ukojenia, a podana na zimno odświeża i orzeźwia. Nie zawiera substancji konserwujących i barwników. Produkt przeznaczony dla dzieci po 9 miesiącu życia. Nasz supermarket online to dobre rozwiązanie dla każdego."
},
[3] #<Product:0x000000083f9898> {
:title => "BOBOVITA Herbata dla dzieci malinowa z dziką różą 200 g",
:description => "Herbatka owocowa Bobovita to łagodny napój dla niemowląt. Ma delikatny aromat i przyjemny smak, dzięki czemu jej picie jest prawdziwą przyjemnością. W chłodne dni przynosi uczucie ukojenia, a podana na zimno odświeża i orzeźwia. Nie zawiera substancji konserwujących i barwników. Produkt przeznaczony dla dzieci po 5 miesiącu życia. Nasz supermarket online to dobre rozwiązanie dla każdego."
},
[4] #<Product:0x000000083f9460> {
:title => "BOBOVITA Herbata dla dzieci malinowa z dziką różą 400 g",
:description => "Herbatka owocowa Bobovita to łagodny napój dla niemowląt. Ma delikatny aromat i przyjemny smak, dzięki czemu jej picie jest prawdziwą przyjemnością. W chłodne dni przynosi uczucie ukojenia, a podana na zimno odświeża i orzeźwia. Nie zawiera substancji konserwujących i barwników. Produkt przeznaczony dla dzieci po 5 miesiącu życia. Zamów już teraz szybka dostawa do domu gwarantowana."
}]
自定义查询提供nil,短语:&#34; herbata owocowa&#34;
(2例)
默认的search()方法和自定义方法都给出相同的结果,短语:&#34; herbata owoc&#34;,前5个结果:
[[0] #<Product:0x00000009f53120> {
:title => "ANIA Ciasteczka orkiszowe z goją 120 g",
:description => "Wyjątkowo zdrowe, chrupiące orkiszowe ciasteczka z owocem Goji. Wypieczone z najlepszej jakości naturalnych składników. Stanowią idealny dodatek do filiżanki ciepłej kawy lub herbaty. Dostępne w szerokiej gamie smakowej. Zapraszamy do zapoznania się z produktami z pozostałych kategorii. Złóż już dzisiaj zamówienie w naszych delikatesach online, gwarantujemy szybką dostawę.\r\n",
},
[1] #<Product:0x0000000a02df00> {
:title => "BIOFIX Herbata Premium Aronia z Acai 20 szt",
:description => "Propozycja od dobrze znanej i cenionej polskiej marki Biofix. Doskonała herbata z owoców aronii, która zadowoli wszystkich miłośników bogatego smaku. Idealna propozycja na każdą porę dnia. Doskonale smakuje z miodem lub dodatkiem plastrów cytryny. Zapraszamy do zapoznania się z produktami z pozostałych kategorii. Zrób już dzisiaj zakupy przez internet, a nasze delikatesy chętnie dostarczą Ci smaczną paczkę.",
},
[2] #<Product:0x0000000a02db90> {
:title => "BOBOVITA Herbata dla dzieci z owoców południowych 200 g",
:description => "Herbatka owocowa Bobovita to łagodny napój dla niemowląt. Ma delikatny aromat i przyjemny smak, dzięki czemu jej picie jest prawdziwą przyjemnością. W chłodne dni przynosi uczucie ukojenia, a podana na zimno odświeża i orzeźwia. Nie zawiera substancji konserwujących i barwników. Produkt przeznaczony dla dzieci po 5 miesiącu życia. Nasz supermarket online to dobre rozwiązanie dla każdego.",
},
[3] #<Product:0x0000000a02d820> {
:title => "BONNE MAMAN Dżem z figi 370 g",
:description => "Dżem przygotowywany według tradycyjnej francuskiej receptury, której korzenie sięgają XVI wieku. Doskonałe proporcje składników i duża zawartość owoców figi wpływają na unikalny smak i aromat tego dżemu. Znakomity do deserów, naleśników, omletów. Może stanowić zdrową alternatywę dla cukru i osłodzić niejedną herbatę. Supermarket internetowy czeka by dostarczyć Ci tę owocową słodycz zamkniętą w słoiczku.",
},
[4] #<Product:0x0000000a02d4b0> {
:title => "BONNE MAMAN Dżem z krojonej pigwy 370 g",
:description => "Dżem przygotowywany według tradycyjnej francuskiej receptury, której korzenie sięgają XVI wieku. Doskonałe proporcje składników, w tym duża zawartość najstaranniej dobranych owoców pigwy wpływają na oryginalny i niepowtarzalny smak i konsystencję dżemu. Świetnie nadaje się do deserów, ciast oraz herbaty. Supermarket internetowy z radością dostarczy Ci słoiczek od Bonne Maman!",
}]
答案 0 :(得分:1)
好的 - 我已经重新格式化SQL以尝试更清楚地了解正在发生的事情。
您需要牢记两点:
如果您选择字典('polish'),那么您应该在处使用它,否则查询的某些部分可能会使用不同的(默认)字典。这可能是你在第一种情况下没有结果的原因。
如果要使用索引,则需要匹配要查询的内容。在第二个查询中,您正在合并并连接一串字符串,因此不能使用任何索引。
但是,在第二个查询中,您似乎始终指定了相同的字典,这就是您获得结果的原因。
如果你确保你的第一个查询始终指定一个波兰字典,那么它有可能使用索引。
您可能希望在单个“文档”上使用单个索引,并且标题和说明的权重也相同(请参阅the manuals)