0

My data structure looks like:

User.first.department
=> "devops maintaining staff"

User.second.department
=> "facility staff"

I'm searching for a search query which does a search with single or multiple arguments for example:

  • search with single argument

    "staff"                # which should return both users
    
  • search with multiple arguments

    "maintaining devops"   # which should return first user
    
  • search with single argument

    "maintaining"          # which should return first user
    
  • another search with single argument

    "facility"             # which should return second user
    

Is there any useful example how to accomplish this?

Eyeslandic
  • 14,553
  • 13
  • 41
  • 54
Stef Hej
  • 1,367
  • 2
  • 14
  • 23

2 Answers2

2

Basically what you're asking for sounds like substring matching. My answer is a "brute force" style of querying and it will become brittle / fall apart really quickly in real-world usage:

# keywords is an array of strings
def keyword_search(keywords)
  query = User

  keywords.each do |keyword|
    query = query.where('department like ?', "%#{keyword}%")
  end

  query.to_a
end

So for your examples you'd get the following queries:

# Returns both users for "staff" 
SELECT "users".* FROM "users" WHERE (department like '%staff%')

# Returns first user for "maintaining devops"
SELECT "users".* FROM "users" WHERE (department like '%maintaining%') AND (department like '%devops%')

# Returns first user for "maintaining devops"
SELECT "users".* FROM "users" WHERE (department like '%maintaining%') 

# Returns first users for "facility"
SELECT "users".* FROM "users" WHERE (department like '%facility%') 

Notice for this type of solution, it's an AND query, so all the keywords will have to match to get a result. The % sign in the query makes the query slightly fuzzier, so for %staff% you'd get matches for the following:

  • staff
  • staffroom
  • flagstaffs
  • overstaff

Which you can adjust by dropping the %s if you're looking for more exact matches.


As Eric suggested, anything more complicated than this is going to require a more advanced solution.

Personally I've used Solr/Websolr and have had good success with it, but the query and search tuning takes a bit of work to understand and implement.

Community
  • 1
  • 1
Gavin Miller
  • 43,168
  • 21
  • 122
  • 188
1

It looks like you need full-text search, which is database dependent.

Here's a related question. For anything more advanced, you might want to look at sphinx and thinking-sphinx.

Community
  • 1
  • 1
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124