我想知道如何用Thinking Sphinx索引模型上的虚拟属性。给定一个Project模型和一些返回由另一个模型中的其他信息派生的布尔值的实例方法,比如用户,其属性是派生的,不在数据库的项目表中。
例如,假设我们有一个方法is_user_eligible
,以便我们可以查询Project.first.is_user_eligible
,并获得真或假的响应。这在ORM中已有效。
如何使用Thinking Sphinx索引此虚拟属性?我能够在我的django项目中索引虚拟属性,该项目位于由Elasticsearch支持的Haystack上。我通过在模型方法上设置@property
装饰器来促进这一点。我想我也应该能够使用Rails / ThinkingSphinx做到这一点,但在尝试索引时我会遇到各种奇怪的SQL错误。我在设置索引时尝试了各种各样的构造(例如,有-vs-索引),并且在索引时都会导致某种SQL错误。
思维斯芬克斯可以实现吗?如果是这样,我如何索引虚拟属性?
答案 0 :(得分:3)
您已明确表示该值不能作为projects
表中的列使用,而是在相关模型上?如果是这样,那么您可以通过关联来引用它:
has user.is_eligible, :as => :is_user_eligible
但是,如果它不是一个列,但可以在SQL查询的上下文中确定,那么您可以使用SQL片段作为属性定义(我知道我的例子是相当人为的,但是应该给你一些想法):
has "(users.foo = 'bar' || users.baz = 'qux')",
:as => :is_user_eligible,
:type => :boolean
如果您指的是索引定义中未使用的关联,则可以强制引用,或提供SQL连接语句:
join users
# or through more than one association:
join users.addresses
# or via your own custom join:
join "INNER JOIN users ON users.project_id = projects.id"
但如果您根本无法通过SQL确定此值,那么使用Thinking Sphinx执行此操作的唯一方法是使用real-time indices 而不是 SQL-支持指数。这意味着,不是引用索引定义中的关联和列,而是引用方法。因此,您的属性将变为:
has is_user_eligible, :type => :boolean
必须指定类型 - 由于列类型,SQL索引可以猜测属性类型,但实时索引没有该参考点。
我意识到实时索引功能的链接是我两年前写的博客文章。然而,这个功能确实有效 - 我和其他人已经在生产中使用了相当长的时间(包括飞行狮身人面像)。
关于has
vs indexes
的主题:如果要将该值用作过滤器或进行排序,则它必须是属性,因此您应该使用{{1} } 方法。但是,如果它是您期望搜索查询匹配的文本数据,那么它应该是一个字段,因此使用has
方法。
当然我建议切换到实时索引:它不需要增量,你可以获得最新的Sphinx记录而无需定期运行'ts:index'(或者根本不使用{{ 1}}你的数据应该是一个过时的状态吗?但请确保将所有索引定义切换为实时,而不是实时和其他SQL支持。