2013-05-09 2 views
5

Я следую за Rails Bates Railscast при полнотекстовом поиске с Postgres, однако он использует postgres 9.1, и я использую 9.2. Он выполняет следующий запрос для выполнения поиска. Это работает для меня, если мой запрос - это одно слово, например «супермен», но если это два слова, например dc comics, или super man, я получаю эту ошибку, которая была просто новой для postgres. Я не могу понять, как исправить. Вы можете помочь?postgres ошибка поискового запроса при использовании пробела

PG::Error: ERROR: syntax error in tsquery: "super man" 
LINE 1: ...articles" WHERE (to_tsvector('english', name) @@ 'super man... 
                  ^
: SELECT "articles".* FROM "articles" WHERE (to_tsvector('english', name) @@ 'super man' or to_tsvector('english', content) @@ 'super man') ORDER BY  ts_rank(to_tsvector(name), plainto_tsquery('super man')) + 
     ts_rank(to_tsvector(content), plainto_tsquery('super man')) 
desc LIMIT 3 OFFSET 0 

запрос от Article.rb

def self.text_search(query) 
    if query.present? 
     rank = <<-RANK 
     ts_rank(to_tsvector(name), plainto_tsquery(#{sanitize(query)})) + 
     ts_rank(to_tsvector(content), plainto_tsquery(#{sanitize(query)})) 
    RANK 

    where("to_tsvector('english', name) @@ :q or to_tsvector('english', content) @@ :q", q: query).order("#{rank} desc") 

    else 
     scoped 
    end 
    end 

ответ

12

@@ используется для сравнения tsvector с tsquery. Вы пытаетесь сравнить tsvector с чем-то, что недействительно tsquery.

'superman' имеет тип text и действительно должен быть обернут в звонок по телефону to_tsquery(). Однако похоже, что postgres попытался помочь вам и принудил его к tsquery для вас, а to_tsquery ('superman') является допустимым запросом.

'super man' имеет тип text и действительно должен быть обернут в звонок по телефону to_tsquery(). Postgres имеет не удалось, чтобы принудить его к tsquery для вас, так как to_tsquery ('super man') is не действительный запрос. Правильный tsquery должен иметь логические операторы, такие как & или |, чтобы рассказать о том, как обрабатывать слова. «супер & человек», вероятно, будет работать.

Чтобы избавить вас от необходимости писать запросы для простых случаев запросов в стиле И, plainto_tsquery делает это немного проще. В вашем случае обернуть :q параметров в вызове plainto_tsquery

plainto_tsquery(:q) 
+0

Спасибо за вашу помощь. Однако я завернул ': q' дважды, как вы видите здесь, хотя он не прерывается при поиске по двум словам, например' was was ', он не возвращает никаких результатов, даже если '' 'существовал' в содержание моего db. это то, что вы ожидаете? в любом случае, чтобы получить результаты поиска по многоязычному поисковому запросу? 'where (" to_tsvector ('english', name) @@ plainto_tsquery (: q) или to_tsvector ('english', content) @@ plainto_tsquery (: q) ", q: query) .order (" # {rank} desc ")' – BrainLikeADullPencil

+1

Читайте на [стоп слова] (http://www.postgresql.org/docs/9.2/static/textsearch-dictionaries.html). Похоже, что «есть» и «были» считаются слишком распространенными в английском словаре, чтобы их индексировать. –

+0

ОК, я вижу. Он возвращает результаты для менее распространенных слов. Благодарю. – BrainLikeADullPencil

Смежные вопросы