Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to quick match an entry with the beginning of a long string?

I have a table articles (:Rails Model but I think the issue is more SQL related) which have a column name permalink. To instance, some of my permalinks :

title-of-article
great-article
great-article-about-obama
obama-stuff-about-him

I want to match a request like great-article-about-obama-random-stuff to great-article-about-obama. Is it possible to do it, avoiding killing performance ?

Thanks to all,

ps : We use Rails 3 and Postgresql (or Sqlite not decided yet for production)

EDIT

We can do something like this, but the main downside is we have to fetched every single permalinks from the table articles :

permalinks = ['title-of-article','great-article','great-article-about-obama','obama-stuff-about-him']
string_to_match = 'great-article-about-obama-random-stuf'
result = permalinks.inject('') do |matched,permalink|
  matched = (string_to_match.include? permalink and permalink.size > matched.size) ? permalink : matched
end
result => 'great-article-about-obama'

I'll love to find a way to do it directly in SQL for obvious performance reason.

like image 776
Hartator Avatar asked Dec 02 '25 03:12

Hartator


1 Answers

Unless using a text-search base technology (w/ postgres : http://www.postgresql.org/docs/8.3/static/textsearch-dictionaries.html + http://tenderlovemaking.com/2009/10/17/full-text-search-on-heroku/ or solr, indexTank) you can do it with :

request = "chien-qui-aboie"
article = nil

while !article do
  article = Article.where("permalink like ?", request+"%").select(:id).first
  request.gsub!(/-[^-]*$/) unless article
end

This will first look for chien-qui-aboie%, then chien-qui%, then chien%.

This will also match "chien_qui_mange" if there is an article "chien_qui_mange" but no one about "chien qui aboie"

That's not optimal because of the number of requests, but that's not that heavy if it's just a look up, and not the normal way of accessing a record.

like image 60
Clément Avatar answered Dec 03 '25 20:12

Clément