1

Texticle検索の一部としてタグの検索を実装しようとしています。texticleは同じモデルから複数のテーブルを検索しないため、システム全体の検索に関するTexticleの提案に従って、PostSearchという新しいモデルを作成することになりました。

class PostSearch < ActiveRecord::Base

  # We want to reference various models
  belongs_to :searchable, :polymorphic => true
  # Wish we could eliminate n + 1 query problems,
  # but we can't include polymorphic models when
  # using scopes to search in Rails 3
  # default_scope :include => :searchable

  # Search.new('query') to search for 'query'
  # across searchable models
  def self.new(query)
    debugger
    query = query.to_s
    return [] if query.empty?
    self.search(query).map!(&:searchable)
    #self.search(query) <-- this works, not sure why I shouldn't use it.
  end

  # Search records are never modified
  def readonly?; true; end

  # Our view doesn't have primary keys, so we need
  # to be explicit about how to tell different search
  # results apart; without this, we can't use :include
  # to avoid n + 1 query problems
  def hash
   id.hash
  end

  def eql?(result)
    id == result.id
  end

end

Postgres DBで、次のようなビューを作成しました。

  CREATE VIEW post_searches AS
  SELECT posts.id, posts.name, string_agg(tags.name, ', ') AS tags
    FROM posts
      LEFT JOIN taggings ON taggings.taggable_id = posts.id 
        LEFT JOIN tags ON taggings.tag_id = tags.id 
  GROUP BY posts.id;

これにより、次のような投稿を取得できます。

SELECT * FROM post_searches
id | name | tags
1    Intro  introduction, funny, nice

だから、それはすべてうまくいくはずだと思われます。残念ながら、PostSearch.new( "funny")を呼び出すと、[nil]([]ではない)が返されます。Texticleのソースコードを見ると、PostSearch.newのこの行のようです。

self.search(query).map!(&:searchable)

ある種のsearchable_columnsメソッドを使用してフィールドをマップしますが、それは正しくありませんか?結果はゼロになります。

別の注意点として、タグフィールドは、テキストタイプからvarcharタイプにキャストしない限り、テキストSQLクエリで検索されません。

要約すると、オブジェクトが見つかったときにオブジェクトがnilにマップされるのはなぜですか?

varcharでない限り、texticleがタグフィールドを無視するのはなぜですか?

4

1 に答える 1

1

Texticle はオブジェクトをnil何もマップしないのではなく、チェックできるようにマップします。これはnil?、存在しないアイテムに対するチェックでエラーが発生するのを防ぐためです。なぜ彼がそのようなことをしたのかについて、テンダーラブ自身に尋ねる価値があるかもしれません。

Texticle が非 varchar を無視する理由については完全に肯定的ではありませんが、Postgres が完全なテーブル スキャンを実行しないようにするためのパフォーマンス セーフガードのようです (超高速のインデックスの作成セクションの) :

クエリを実行するすべてのテキスト/文字列列にインデックスを追加する必要があります。そうしないと、Postgresql はインデックスを使用する代わりにフル テーブル スキャンに戻ります。

于 2012-04-26T20:19:47.670 に答える