Dynamic Attributes in Search Results?

81 views
Skip to first unread message

peter

unread,
Dec 17, 2009, 10:30:02 PM12/17/09
to Thinking Sphinx
Simple problem: I'm using the Savage-Beast forums plugin. It's great.
I'm trying to replace its simple SQL search function with the powerful
Sphinx/TS. Straightforward model relationship you'd expect for a
forum:

Form has_many Topic(s) which has_many Post(s). I'm indexing only the
Post model for now:

class Post
define_index do
indexes body
has user_id, created_at, updated_at
has topic(:title), :as => :topic_title
has topic.forum(:name), :as => :forum_name
end
end

Obviously, topic_title and forum_name would be the dynamic attributes
in this setup.

Running Post.search, I was hoping that each Post result would include
these two dynamic attributes. But they don't. And I couldn't find any
options to run with Post.search that would slurp in these attributes.
(Savage-Beast's code wants them.)

Oddly enough, if I run the sql_query that appears in the sphinx config
file, that search does nicely include the dynamic attributes. That
query is clearly constructed from the "define_index" code above.
Evidently, Post.search doesn't use that sql_query from config.

Sorry for the long post. My simple question is the following: Is there
an elegant way to have Post.search return Post objects that contain
the two dynamic attributes (topic_title and forum_name) defined in the
"define_index" code?

Thanks

Peter

Pat Allan

unread,
Dec 18, 2009, 8:18:06 PM12/18/09
to thinkin...@googlegroups.com
Hi Peter

Are you wanting those two columns as fields or attributes? It sounds like the former, though you've got it set up as the latter. Perhaps this index definition is more appropriate?:

define_index do
indexes body
indexes topic.title, :as => :topic_title
indexes topic.forrum(:name), :as => :forum_name
has user_id, created_at, updated_at
end

In case you're not familiar with the difference between fields and attributes, the docs cover this pretty well (I think - but if I'm wrong, please tell me! :)
http://freelancing-god.github.com/ts/en/sphinx_basics.html

Cheers

--
Pat

> --
>
> You received this message because you are subscribed to the Google Groups "Thinking Sphinx" group.
> To post to this group, send email to thinkin...@googlegroups.com.
> To unsubscribe from this group, send email to thinking-sphi...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/thinking-sphinx?hl=en.
>
>

peter

unread,
Dec 18, 2009, 9:18:05 PM12/18/09
to Thinking Sphinx
On Dec 18, 5:18 pm, Pat Allan <p...@freelancing-gods.com> wrote:
> Hi Peter
>
> Are you wanting those two columns as fields or attributes?

Thanks for the reply Pat. I actually just want attributes. Don't need
to search the text of the topic_title or forum_name. But I do need
those two to appear as "special guest star" attributes of the Post
objects returned by Post.search.

I did try turning those two data elements into fields, rather than
attributes, just as you described. But this didn't seem to cause them
to appear as part of the Post object search results. i.e. After
changing these two to fields as your describe, and rebuilding the
index, here is a Ruby console request showing that these two are
missing:

>> Post.search.first.attribute_names
=> ["body", "body_html", "created_at", "forum_id", "id", "topic_id",
"updated_at", "user_id"]

The attributes that are present in the resulting Post objects are
simply the columns from the posts table. "body" is one of those
columns. And define_index instructs Sphinx to index that field.

But although Sphinx is also instructed to index topic_title and
forum_name, and even though I can sort on those two (e.g. Post.search
('blah', :order => :topic_title), I can't access them as attributes of
the search result objects.

Doesn't it seem like the search objects returned by TS should contain
as attributes all of the "indexes" and "has" attributes declared in
"define_index"? Or, at least, it seems there should be an option to
include when running TS search to have all of the define_index
attributes included as attributes present in the resulting objects.

For now, I have to hack up some ugly code, taking the TS array of Post
objects returned by Post.search, and, for each object, adding back in
those two dynamic attributes. It's not that painful in terms of
performance since only 20 results are returned at a time (meaning an
extra 40 quick database hits per results page -- i.e. 20 hits on Topic
+ 20 hits on Forum), and my site has low traffic. But still, like I
said: ugly. Hopefully temporary. :)

Thanks for your help.

Peter

Pat Allan

unread,
Dec 25, 2009, 11:08:07 PM12/25/09
to thinkin...@googlegroups.com
Hi Peter

Firstly, I was a little confused with your example, but attribute_names is an AR method, not something Thinking Sphinx adds.

Secondly, while you can access the attribute values returned by Sphinx using the sphinx_attributes hash (see below), Sphinx doesn't store string attributes as strings, but as integers - they're useful for sorting, but not much else.

Post.search.first.sphinx_attributes

You can pass in :includes to your search call though, and it will be handed to ActiveRecord in the underlying find call when instantiating search results. This may keep the extra queries down instead?

--
Pat

Reply all
Reply to author
Forward
0 new messages