19 comments

  • simonw 2 hours ago
    This is really cool. I've built things on PostgreSQL ts_vector() FTS in the past which works well but doesn't have whole-index ranking algorithms so can't do BM25.

    It's a bit surprising to me that this doesn't appear to have a mechanism to say "filter for just documents matching terms X and Y, then sort by BM25 relevance" - it looks like this extension currently handles just the BM25 ranking but not the FTS filtering. Are you planning to address that in the future?

    I found this example in the README quite confusing:

      SELECT * FROM documents
      WHERE content <@> to_bm25query('search terms', 'docs_idx') < -5.0
      ORDER BY content <@> 'search terms'
      LIMIT 10;
    
    That -5.0 is a magic number which, based on my understanding of BM25, is difficult to predict in advance since the threshold you would want to pick varies for different datasets.
    • tjgreen 1 hour ago
      I actually don't love this example either, for the reasons you mention, but at some point we had questions about how to filter based on numeric ranking. Thanks for the reminder to revisit this.

      Re filtering, there are often reasonable workarounds in the SQL context that caused me to deprioritize this for GA. With your example, the workaround is to apply post-filtering to select just matches with all desired terms. This is not ideal ergonomics since you may have to play with the LIMIT that you'll need to get enough results, but it's already a familiar pattern if you're using vector indexes. For very selective conditions, pre-filtering by those conditions and then ranking afterwards is also an option for the planner, provided you've created indexes on the columns in question.

      All this is just an argument about priorities for GA. Now that v1.0 is out, we'll get signal about which features to prioritize next.

      • mbreese 50 minutes ago
        While we’re talking about filtering — is there a way to set a WHERE clause when you’re setting up the index? I’ve been working on this a lot recently for a hybrid vector search in pg. One of the things that I’m running up against is setting a good BM25 index for a subset of a table (the where clause). I have a document subsets with very different word frequencies, so I’m trying to make sure that the search works on a set subset.

        I think I can also setup partitions for this, but while you’re here… I’m very excited to start to roll this out.

        • tjgreen 40 minutes ago
          Partitions would be one option, and we've got pretty robust partitioned table support in the extension. (Timescaledb uses partitioning for hypertables, so we had to front-load that support). Expression indexes would be another option, not yet done but there is a community PR in flight: https://github.com/timescale/pg_textsearch/pull/154
  • shreyssh 1 hour ago
    Nice work. pg_search has been on my radar for a while, having BM25 natively in Postgres instead of bolting on Elasticsearch is a huge DX win. Curious about the index build time on larger datasets though. I'm working with ~2M row tables and the bottleneck for most Postgres extensions I've tried isn't query speed, it's the initial indexing. Any benchmarks on that?
    • tjgreen 1 hour ago
      Yep, there are numbers in the blog post and repo. We are able to index MS-MARCO v2 (138M documents, around 50GB of raw data) in a bit under 18 minutes.
      • tjgreen 1 hour ago
        For 2M scale dataset, you should be able to index in about 1 minute on low-end hardware. See the MS-MARCO v1 (8M documents) numbers, measured on cheap Github runners.
  • maweaver 23 minutes ago
    I've been doing some RAG prototypes with hybrid search using pg_textsearch plus pgvector and have been very pleased with the results. Happy to see a 1.0 release!
  • jascha_eng 2 hours ago
    FWIW TJ is not your average vibe coder imo: https://www.linkedin.com/in/todd-j-green/

    In september he burned through 3000$ in API credits though, but I think that's before we finally bought max plans for everyone that wanted it.

  • andai 1 hour ago
    Can you explain this in more detail? Is this for RAG, i.e. combining vector search with keyword search?

    My knowledge on that subject roughly begins and ends with this excellent article, so I'd love to hear how this relates to that.

    https://www.anthropic.com/engineering/contextual-retrieval

    Especially since what Anthropic describes here is a bit of a rube Goldberg machine which also involves preprocessing (contextual summarization) and a reranking model, so I was wondering if there's any "good enough" out of the box solutions for it.

    • tjgreen 58 minutes ago
      Yes, hybrid search is one of the main current use cases we had in mind developing the extension, but it works for old-fashioned standalone keyword-only search as well. There is a lot of art to how you combine keyword and semantic search (there are entire companies like Cohere devoted to just this step!). We're leaving this part, at least for now, up to application developers.
  • mattbessey 43 minutes ago
    Please oh please let GCP add this to the supported managed Postgres extensions...
    • tjgreen 25 minutes ago
      A little birdie told me that efforts are underway to support the extension in Alloy, at least!
  • Unical-A 1 hour ago
    Impressive benchmarks. How does the BM25 implementation handle high-frequency updates (writes) while maintaining search latency? Usually, there's a trade-off between ingest speed and search performance in Postgres-based full-text search.
    • tjgreen 53 minutes ago
      There is indeed such a tradeoff. The architecture is designed with an eye towards making this tradeoff tunable (frequency of memtable spills, aggressiveness of compaction) but the work here is not yet finished. We chose to prioritize optimizing bulk-indexing and query performance for GA, since this is already enough for many applications. I'm excited to get to the point where we have brag-worthy benchmark numbers for high-frequency updates as well!
  • bradfox2 23 minutes ago
    Thank you!! Goodbye manticore if this works.
  • piskov 20 minutes ago
    On a tangent note it’s amazing how hard it is to have a good case-insensitive search in Postgres.

    In SQL Server you just use case-insensitive collation (which is a default) and add an index (it’s the only one non-clustered) and call it a day.

    In postgres you need to go above and beyond just for that. It’s like postgres guys were “nah dog, everybody just uses lowercase; you don’t need to worry of people writing john doe as John Doe)”.

    And don’t get me started with storing datetime with timezone (e.g “4/2/2007 7:23:57 PM -07:00“). In sql server you have datetimeoffset; in Postgres you fuck off :-)

  • zephyrwhimsy 54 minutes ago
    Input quality is almost always the actual bottleneck. Teams spend months tuning retrieval while feeding HTML boilerplate into their vector stores.
  • gmassman 1 hour ago
    Very exciting! Congrats on the release, this will be a huge benefit to all folks building RAG/rerank systems on top of Postgres. Looking forward to testing it out myself.
    • 3abiton 1 hour ago
      This is pretty much my case right now. BM25 is so useful in many cases and having with with postgres is neat!
  • jackyliang 1 hour ago
    VERY excited about this, literally just looking to build hybrid search using Postgres FTS. When will this be available on Supabase?
    • tjgreen 1 hour ago
      You'll have to ask Supabase!
  • timedude 51 minutes ago
    When is this available on AWS in Aurora? Anyone from AWS here, add it pronto
  • devmor 29 minutes ago
    This is really cool to see! I've been using BM25+sqlite-vec for contextual search projects for a little while, it's a great performance addition.
  • gplprotects 2 hours ago
    > ParadeDB, is guarded behind AGPL

    What a wonderful ad for ParadeDB, and clear signal that "TigerData" is a pernicious entity.

    • lsaferite 1 hour ago
      You: > "TigerData" is a pernicious entity

      TigerData: > pg_textsearch v1.0 is freely available via open source (Postgres license)

      They deemed AGPL untenable for their business and decided to create an OSS solution that used a license they were comfortable with and they are somehow "pernicious"? Perhaps take a moment to reflect on your characterization of a group that just contributed an alternative OSS project for a specific task. Not only that, but they used a VERY permissive license. I'd argue that they are being a better OSS community member for selecting a more permissive license.

    • tjgreen 1 hour ago
      Okay then!
  • benjiro3000 1 hour ago
    [dead]
  • zephyrwhimsy 53 minutes ago
    [dead]