1

PostgreSQL Railscastで全文検索を実行しましたが、奇妙な動作が発生しています。

たとえば、「police」を検索すると結果が得られませんが、「polic」を検索すると結果が得られます。(警察は私が探しているコンテンツに存在します)。また、一部の結果はまったく返されませんが、単語が大きいか小さいかにかかわらず、単語が存在することはわかっています。

Rails dbconsoleを起動すると、psql(9.1.4)を使用していると表示され、アプリの残りの部分も正常に機能しているようです。

インデックスなどを再構築する必要がありますか?

私はPGgemとpostgres_extgemを使用していますが、texticleまたはpg_search gemは使用していません(追加機能は実際には必要ないため)。

それ以外の点では、私のコードはスクリーンキャストと同じです。

def self.text_search(query)
  if query.present?
    rank = "ts_rank(to_tsvector(name), plainto_tsquery(#{sanitize(query)}))"
    where("to_tsvector('english', name) @@ :q 
           or to_tsvector('english', content) @@ :q", q: query).order("#{rank} desc")
  else
    scoped
  end
end

そして、私はそのようにインデックスを作成しました:

class AddSearchIndexToArticles < ActiveRecord::Migration
  def up
    execute "create index articles_name on articles using gin(to_tsvector('english', name))"
    execute "create index articles_content on articles using gin(to_tsvector('english', content))"
  end
end

興味深いことに、where呼び出しでto_tsvectorへの呼び出しを削除すると、次のようになります。

def self.text_search(query)
  if query.present?
    rank = "ts_rank(to_tsvector(name), plainto_tsquery(#{sanitize(query)}))"
    where("name @@ :q 
           or content @@ :q", q: query).order("#{rank} desc")
  else
    scoped
  end
end

...期待どおりに機能します(インデックスが無視されているように見えるため、非常に遅いことは別として)

何が起こっているのかアイデアはありますか?

アップデート:

フルロギングをオンに切り替えた後、実行されているSQLは次のとおりです。

LOG:  statement: SELECT 1
LOG:  statement: SELECT  "dogs".* FROM "dogs"  WHERE (to_tsvector('english', name) @@ 'wary' 
               or to_tsvector('english', other_names) @@ 'wary'
               or to_tsvector('english', origin) @@ 'wary'
               or to_tsvector('english', kusa) @@ 'wary') ORDER BY         ts_rank(to_tsvector(name), plainto_tsquery('wary'))
     desc LIMIT 10 OFFSET 0
LOG:  statement: SELECT 1
LOG:  statement: SELECT 1

私はSQLの専門家ではありませんが、クエリは問題ないように見えますか?

また、それが関連しているかどうかはわかりませんが、ログファイルには次のようなものもたくさんあります。

FATAL:  lock file "postmaster.pid" already exists
HINT:  Is another postmaster (PID 821) running in data directory "/usr/local/var/postgres"?

自作でpostgresをインストールし、9.1.4を使用しています

4

1 に答える 1

4

警察という言葉が次のようにどのように変換されるかを考えてみましょうto_tsvector

select to_tsvector('english','police');

結果:

to_tsvector
-------------
 'polic':1

それを警察と直接比較すると、一致しません。

select to_tsvector('english','police') @@ 'police' as match;

結果:

マッチ
----------
 f

(fは、このコンテキストではブール値のfalseです)。

ただし、の結果と比較するとplainto_tsquery、次のように一致します。

select to_tsvector('english','police') @@ plainto_tsquery('english','police')  as match;

結果:

マッチ
-------
 t

結論:tsvectorを単語と直接一致させたり、、、plainto_tsqueryまたはの結果と一致させたりしないでto_tsqueryください。


他にも強化したいことがあります。現在、クエリにはto_tsvector英語の構成が明示的に渡された呼び出しと、この引数なしの呼び出し(ORDER BY句内)の両方が含まれています。この場合、デフォルトでdefault_text_search_configパラメーターの現在の値になります。このパラメータが英語と異なる場合、特定の式で予期しない結果が生じる可能性があります。このパラメーターを一貫して渡すか、一貫して省略することをお勧めします。後者の場合、簡潔であるという利点があり、特定の言語のハードコーディングを回避できます。

于 2012-08-19T10:21:14.260 に答える