Forum: Ferret bilingual site: exclude fields set from query

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Alain R. (Guest)
on 2007-05-16 22:56
(Received via mailing list)
Hi all,

Is there a way to have searches no use some indexed fields, when
processing a query?

context:
I have a model Foo that holds some information in two languages :
  - text1_nl, text2_nl, text3_nl
and
  - text1_en, text2_en, text3_en
Some other fields are common to both languages and indexed as well
   - first_name, last_name

Depending on the visitor language choice I need to exclude the first
three, or last three fields when query processing. Is this doable
relatively simply?
I guess I could use two indexes, but I'd like to keep using
acts_as_ferret if possible.


TIA.


Alain R.
Doug S. (Guest)
on 2007-05-17 00:43
(Received via mailing list)
I would setup your models differently, using Single-Table Inheritance
(STI).  (You can get more info on it by Googling "rails single table
inheritance".)  For your example, you'd have a table with columns like:

id, type, first_name, last_name, text1, text2, text3

Then, you'd have a model like:

class Text << ActiveRecord::Base
   acts_as_ferret(... declare all fields here )
end

You'd then subclass this with two other classes:

class EnglishText << Text
end

class DutchText << Text
end

Then, to search one or the other, use:

EnglishText.find_by_contents("english query")

DutchText.find_by_contents("dutch query")

That's a rough idea without exact code, but it should hopefully get you
started.

Thanks,

Doug
Alain R. (Guest)
on 2007-05-17 01:43
(Received via mailing list)
Doug

 > I would setup your models differently, using Single-Table Inheritance

STI would be impractical (I don't want to add a useless "type"
column), but plain inheritance sounds like a very good idea.

 > class Text << ActiveRecord::Base
 >    acts_as_ferret(... declare all fields here )
 > end>
 > You'd then subclass this with two other classes:
 >
 > class EnglishText << Text
 > end
 > class DutchText << Text
 > end

I guess you meant :

 class Text << ActiveRecord::Base
 end
 class EnglishText << Text
    acts_as_ferret :fields => [name, text_en]
 end
 class DutchText << Text
    acts_as_ferret :fields => [name, text_nl]
 end

That would indeed allow to call :
 > EnglishText.find_by_contents("english query")
 > DutchText.find_by_contents ("dutch query")


Clean and simple.
Thanks a lot.

Alain R.
----
http://blog.ravet.com
Jens K. (Guest)
on 2007-05-21 15:33
(Received via mailing list)
On Wed, May 16, 2007 at 08:55:46PM +0200, Alain R. wrote:
> Some other fields are common to both languages and indexed as well
>    - first_name, last_name
>
> Depending on the visitor language choice I need to exclude the first
> three, or last three fields when query processing. Is this doable
> relatively simply?
> I guess I could use two indexes, but I'd like to keep using
> acts_as_ferret if possible.

A query string like

text1_nl|text2_nl|text3_nl|first_name|last_name:query

will only search for query in the named fields.

Jens

--
Jens Krämer
webit! Gesellschaft für neue Medien mbH
Schnorrstraße 76 | 01069 Dresden
Telefon +49 351 46766-0 | Telefax +49 351 46766-66
removed_email_address@domain.invalid | www.webit.de

Amtsgericht Dresden | HRB 15422
GF Sven Haubold, Hagen Malessa
Alain R. (Guest)
on 2007-05-21 20:04
(Received via mailing list)
Jens,

 > A query string like
 >    text1_nl|text2_nl|text3_nl|first_name|last_name:query
 > will only search for query in the named fields.

Thanks.

Is this the proper syntax for multi-words queries:

  first_name|last_name:(jo* OR va*)
?

Alain
Benjamin K. (Guest)
on 2007-05-21 20:50
(Received via mailing list)
Hey Alain,

finally jumped on board? :-) hope to see you in berlin in a few month ..

> Is this the proper syntax for multi-words queries:
>
>   first_name|last_name:(jo* OR va*)

i would suggest to use the OO-Syntax for more complex queries .. like
that:

query = BooleanQuery.new
[ :first_name, :last_name ].each do |key|
   query.add_query( PrefixQuery.new( key, 'jo' ), :should )
end


for a people-livesearch, i do something like [1]:

def build_livesearch_query( fields, q )
   q = filter_special_characters( q ) # custom method
   query = BooleanQuery.new
   fields.uniq.each do |field|
     sq = SpanNearQuery.new(:in_order => true, :slop => 1)
     terms = analyze_query(q, field) # custom method
     terms.each do |term|
       sq << SpanPrefixQuery.new( field, term )
     end
     query << sq
   end
   query
end

i call that like

build_livesearch_query( [:first_name, :last_name, :email, q )     # q
is an array of search words

Ben


[1] all of the code at http://bugs.omdb.org/browser/trunk/lib/omdb/
ferret/local_search.rb
Alain R. (Guest)
on 2007-05-21 21:10
(Received via mailing list)
Hi Ben,

  > Hey Alain,
  > finally jumped on board? :-) hope to see you in berlin in a few
months

Can't wait to register. My credit card is on the starting-blocks.


 > > Is this the proper syntax for multi-words queries:
 > >   first_name|last_name:(jo* OR va*)
 >
 > i would suggest to use the OO-Syntax for more complex queries .. like
 > query = BooleanQuery.new


I'm refactoring/upgrading an "old" (1-year) app, where I used to do
all the ferret index stuff myself (callbacks, queries, ..), to the
mucho simpler interface offered by acts_as_ferret. AFAIK, aaf only
works with string queries, so if there is a string-based solution that
works, I'd rather use this one. If there is none, I'll bite the bullet
and follow your advice. "A man's got to do, what a man's got to do"


Alain

--
Alain R.
Benjamin K. (Guest)
on 2007-05-21 23:03
(Received via mailing list)
>
> I'm refactoring/upgrading an "old" (1-year) app, where I used to do
> all the ferret index stuff myself (callbacks, queries, ..), to the
> mucho simpler interface offered by acts_as_ferret. AFAIK, aaf only
> works with string queries, so if there is a string-based solution that
> works, I'd rather use this one. If there is none, I'll bite the bullet
> and follow your advice. "A man's got to do, what a man's got to do"

Alain,

i'm no AAF expert, but afaik most methods of aaf are using
find_id_by_contents.. which is accepting a query parameter..

that query parameter gets forwarded to ferrets own search_each.

search_each accepts strings or ferret query objects.. so i would
assume that you can pass a OO-Query to AAF. And anything else
would have surprised me.. as Jens code is quite sophisticated :-)


Ben
This topic is locked and can not be replied to.