カスタムフィールドiso8601値で並べ替えてトピックを取得する方法

limit(10) ですでにその動作を行うはずです :slight_smile:

以下のような実装が有効だと思います(ただし未検証です):

Topic.where("category_id in (?)", [cat_id])
         .where("closed = ?", false)
         .joins("LEFT JOIN topic_custom_fields import_tcf ON import_tcf.topic_id = topic.id AND topic_custom_fields.name = 'importedSortDate'")
         .order("TIMESTAMP import_tcf.value")
         .order("created_at desc")
         .limit(10)

問題は、Postgres に日付文字列をタイムスタンプにキャストさせる処理が非常に非効率になる点です。すべてのトピックに対して変換を行った上で、最初の10件を選ぶ必要があります。

ここで考えられるいくつかのオプションがあります。日付を ISO8601 形式ではなく「エポックからの秒数」として保存する方法です。これにより、Postgres でのソートがはるかに容易になります。あるいは、データベースマイグレーションを使用して topic_custom_fields テーブルに TIMESTAMP value 用のインデックスを追加することも可能です。