I thought this was a great article, and trigram indexes are definitely an amazing tool to have in the arsenal. I think PostgreSQL fulltext search (with tsvector, tsquery etc.) is given an unfairly bad rap though. I'm not sure that "full text search works best when the text vectors are stored in physical columns with an index" is true - in my experience there's no performance penalty to just indexing the tsvector expr…
> I'm not sure that "full text search works best when the text vectors are stored in physical columns with an index" is true It's mostly based on my past experiences. At my previous gig we indexed quite a bit of data using PostgreSQL's full text search system and we noticed significantly improved performance when using physical columns containing text vectors over just using GIN indexes. It's been a while so the deta…
Fast Search Using PostgreSQL Trigram Indexes
11–20 of 33 posts
Re: Fast Search Using PostgreSQL Trigram Indexes
#12next on the map: discovering how shitty dictionary management is, the joys of NLP, and abandoning the project entirely because you realize all this stuff has already been solved in 3 or 4 different ways and the getting-the-data-from-the-database-to-the-search-engine process isn't really that bad, and pulling your hair out from customers asking insane questions because they don't understand how search engines actually work and why can't this be like google? can't you just do it how google does it, even though you don't have $100B and 50,000 employees?
i realize this is a product feature but i have ptsd on this topic so i had to vent.
Re: Fast Search Using PostgreSQL Trigram Indexes
#13Earlier quoted context omitted.
> I'm not sure that "full text search works best when the text vectors are stored in physical columns with an index" is true It's mostly based on my past experiences. At my previous gig we indexed quite a bit of data using PostgreSQL's full text search system and we noticed significantly improved performance when using physical columns containing text vectors over just using GIN indexes. It's been a while so the deta…
Ah ok, interesting :). We were weighing up exactly these kind of tradeoffs a few weeks ago, and the benchmarks we did put the 2 approaches more or less neck and neck, so maybe PG has managed to optimize things a bit? Or, our search is over hundreds of thousands of rows, so maybe things only slow down in the millions and above...
Re: Fast Search Using PostgreSQL Trigram Indexes
#14Earlier quoted context omitted.
One of the perks of using columns is that you can setup multiple columns with different dictionaries and specify which one you're searching against. I'm not sure how easy it would be to ensure that the index would get picked up if searching on a weighted field with multiple columns specified or if it would require that the program know in advance what those columns were. Would the order matter for the index to be use…
There's nothing stopping you indexing multiple columns with different dictionaries either :). And indexing works beautifully with multiple weighted columns. The related records point is true though - indexes don't help if you're trying to implement multi-table search. Although then I'd argue a materialized view (refreshed with triggers) might be better than putting more columns into one of the data tables.
Re: Fast Search Using PostgreSQL Trigram Indexes
#15ah yes, the old 're-implement the search engine inside the database' project, undoubtedly put up on the board because someone is tired of their get-the-data-from-the-database-to-the-search-engine process breaking constantly. next on the map: discovering how shitty dictionary management is, the joys of NLP, and abandoning the project entirely because you realize all this stuff has already been solved in 3 or 4 differe…
Re: Fast Search Using PostgreSQL Trigram Indexes
#16Hi! Author in question here, if anybody would like to know more about this particular feature I'll be happy to answer any questions. The changes discussed in this article are currently available on GitLab.com, 8.6 will be released on the 22nd as usual.
Why bother supporting both MySQL and Postgres for the backend? Wouldn't picking one ( ~cough~ Postgres ) simplify things? From my experience, attempting to support multiple backend stores leads to either crippled functionality, i.e. lowest common denominator CRUD usage, or lots of messy if/then logic to use DB specific features.
Many of our customers have large MySQL clusters running. It's very convenient to be able to just plug GitLab into that.
We have no intention in dropping it in the near future. For instance, our Pivotal Cloud Foundry (PCF) tile makes use of the MySQL cluster in PCF [0].
For those reasons, we'll continue to support MySQL and make sure it's performant.
Re: Fast Search Using PostgreSQL Trigram Indexes
#17You can use to_tsvector('simple', column_name) if you don't want a language-specific parse, or you can make your own.
"This means that searching for “yorick” or “peterse” will match the data, but searching for “yor” will not"
You can use prefix searching:
select to_tsvector('simple', 'Yorick Peterse') @@ to_tsquery('simple', 'yor:*') --true
Heck you can even do suffix searching: select to_tsvector('simple', reverse('Yorick Peterse')) @@ to_tsquery('simple', reverse('rick') || ':*')
The real problem with PostgreSQL's text search is that it doesn't support BM 25 or TFIDF out of the boxRe: Fast Search Using PostgreSQL Trigram Indexes
#18Re: Fast Search Using PostgreSQL Trigram Indexes
#19I recently worked on this problem for a project and came up with a more robust solution using pre-computed Levenshtein indexes. You've probably heard of Levenshtein distance as a measure of word similarity. It counts the number of single-character edits that are required to transform one string into another. For example "vodka" and "votka" have a Levenshtein distance of 1.
Using a related approach (single character edits) it's possible to build a so-called Levenshtein index.
The major issue with a vanilla Levenshtein index is that it's impractically large. There is a way to make a space / time trade-off however that makes it much smaller. The basic idea is that instead of generating all Levenshtein variations for a word you only use the set of variations created by deleting single characters for a word.
Since that doesn't match all possible variations we have to compensate somehow. For example with a full index "votka" would be in the set of variations for "vodka" which means if we had misspelled vodka when searching for it we'd still get a match. With our deletions-only index, however, we'd get "voka" as our closest match. To work around this, we generate the deletion-only variations of our search term as well. In this case our search term "vodka" would become "odka", "vdka", "voka", etc. and each of those terms would be matched against the index. That means our query is slower overall as it contains a number of sub-queries but in practice it's more than fast enough.
I wrote a meandering blog post about it here: http://lattejed.com/writing-an-embedded-full-text-search-eng...
There are some additional ideas in there such as how to make a Levenshtein index handle prefix matches better (for e.g., incremental search) that may be helpful if you need to implement something like this.
If you do read that I'd like to point out that I no longer recommend LevelDB. That doesn't change anything of importance in the post though.
Re: Fast Search Using PostgreSQL Trigram Indexes
#20Trigrams are a very straightforward solution to this but they have one major limitation: They break with misspellings / alternative spellings. For example the words "vodka" and "votka" share no trigrams yet are obviously very similar. I recently worked on this problem for a project and came up with a more robust solution using pre-computed Levenshtein indexes. You've probably heard of Levenshtein distance as a measur…