ruby-on-railsferretacts-as-ferret

ferret / acts_as_ferret : Specify that a field should be blank


This relates to the lucene-based search engine, Ferret. https://github.com/dbalmain/ferret

Let's say i have a model with two fields, myfield1 and myfield2. I want to get records that have myfield equal to "foo", or that have null (or an empty string) for myfield but have myfield2 set to "foo".

I DON'T want to get records that have, for example, myfield = "bar" and myfield2 = "foo". So, it's not as simple as just saying "myfield:foo || myfield2: foo" - i only want to look at myfield2 if myfield is empty.

The sql equivalent would be where (myfield = 'foo') or ((myfield is null or myfield = '') and myfield2 = 'foo'). What would the ferret search string equivalent of this be?

The following doesn't work, but it's an example of the sort of thing I'm after:

"myfield:foo || (myfield:<blank> && myfield2:foo)"

thanks, Max

BTW in case it's relevant i'm using acts_as_ferret in ruby on rails, but i think my question really just relates to a ferret search string. I'm using the ferret gem, v=0.11.6

EDIT: Slightly dirty-feeling solution below, would still like to know if it's possible just with the query string like above.

OK, i got around this by adding a new method, "myfield_blank":

def myfield_blank
  myfield_blank?.to_s
end

then adding myfield_blank => {}, to my acts_as_ferret index definition. So now i can say

"myfield:foo || (myfield_blank:true && myfield2:foo)" 

This works but like I say i'd still like to know if I can just do it in the query, without making new fields: this approach would be unacceptably hacky if i wanted to do it for lots of different fields. thanks


Solution

  • According to the source ?* should match any nonempty string, so you can try to do it this way:

    'myfield:"foo" || (-myfield:"?*" && myfield2:"foo")'
    

    And also I don't really see why 'myfield:"foo" || (myfield:"" && myfield2:"foo")' shouldn't work, but you probably already tried it...