索引虚拟属性 Thinking Sphinx
Index virtual attribute Thinking Sphinx
我想知道如何使用 Thinking Sphinx 为模型的虚拟属性编制索引。给定一个 Project 模型和一些实例方法,其中 returns 一个布尔值是从另一个模型的一些其他信息派生的,比如 Users,其属性是派生的并且不在数据库中的项目 table 上。
例如,假设我们有一个方法 is_user_eligible
,这样我们就可以查询 Project.first.is_user_eligible
,并得到真或假的响应。这已经在 ORM 中起作用了。
如何使用 Thinking Sphinx 索引此虚拟属性?我能够在我的 django 项目中索引虚拟属性,该项目位于 Elasticsearch 支持的 Haystack 上。我通过在模型方法上使用 @property
装饰器来促进这一点。我认为我也应该能够使用 Rails/ThinkingSphinx 执行此操作,但是在尝试索引时我遇到了各种奇怪的 SQL 错误。我在设置索引时尝试了各种不同的结构(例如,有 -vs- 索引),并且在索引时都会导致某种 SQL 错误。
Thinking Sphinx 可以吗?如果是这样,我如何索引虚拟属性?
您已明确表示该值在 projects
table 中不可作为列使用,但它是否在关联模型中可用?如果是这样,那么您可以通过协会参考它:
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 索引可以根据列类型猜测属性类型,但实时索引没有那个参考点。
我意识到 link 实时索引功能是我两年前写的一篇博客 post。然而,这个功能确实有效——我和其他人已经在生产中使用它很长一段时间了(包括 Flying Sphinx)。
关于has
vs indexes
的话题:如果你想将值用作过滤器或排序,那么它必须是一个属性,因此你应该使用has
方法。但是,如果您希望搜索查询匹配的是文本数据,那么它应该是一个字段,因此可以使用 indexes
方法。
当然,我还是建议切换到实时索引:它消除了对增量的需求,并且您无需定期 运行 'ts:index' 即可获得最新的 Sphinx 记录(或完全 - 如果您的数据最终处于过时状态,请使用 ts:generate
)。但是请确保将 所有 索引定义切换为实时,而不是让一些实时和其他 SQL-backed.
我想知道如何使用 Thinking Sphinx 为模型的虚拟属性编制索引。给定一个 Project 模型和一些实例方法,其中 returns 一个布尔值是从另一个模型的一些其他信息派生的,比如 Users,其属性是派生的并且不在数据库中的项目 table 上。
例如,假设我们有一个方法 is_user_eligible
,这样我们就可以查询 Project.first.is_user_eligible
,并得到真或假的响应。这已经在 ORM 中起作用了。
如何使用 Thinking Sphinx 索引此虚拟属性?我能够在我的 django 项目中索引虚拟属性,该项目位于 Elasticsearch 支持的 Haystack 上。我通过在模型方法上使用 @property
装饰器来促进这一点。我认为我也应该能够使用 Rails/ThinkingSphinx 执行此操作,但是在尝试索引时我遇到了各种奇怪的 SQL 错误。我在设置索引时尝试了各种不同的结构(例如,有 -vs- 索引),并且在索引时都会导致某种 SQL 错误。
Thinking Sphinx 可以吗?如果是这样,我如何索引虚拟属性?
您已明确表示该值在 projects
table 中不可作为列使用,但它是否在关联模型中可用?如果是这样,那么您可以通过协会参考它:
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 索引可以根据列类型猜测属性类型,但实时索引没有那个参考点。
我意识到 link 实时索引功能是我两年前写的一篇博客 post。然而,这个功能确实有效——我和其他人已经在生产中使用它很长一段时间了(包括 Flying Sphinx)。
关于has
vs indexes
的话题:如果你想将值用作过滤器或排序,那么它必须是一个属性,因此你应该使用has
方法。但是,如果您希望搜索查询匹配的是文本数据,那么它应该是一个字段,因此可以使用 indexes
方法。
当然,我还是建议切换到实时索引:它消除了对增量的需求,并且您无需定期 运行 'ts:index' 即可获得最新的 Sphinx 记录(或完全 - 如果您的数据最终处于过时状态,请使用 ts:generate
)。但是请确保将 所有 索引定义切换为实时,而不是让一些实时和其他 SQL-backed.