Skip to content
Advertisement

Database search results with context

I’ve built a system for archiving, aggregating, and indexing my IM history across different platforms (e.g. MSN Messenger, Hangouts, WhatsApp). The data is currently stored in an SQLite3 database, and relevant parts of the schema look something like this:

There are also NOT NULL constraints on all columns, but I skipped those to make the schema a little easier to read.

What I’d like to do is implement “search with context”, where records around (before/after) the result are shown. Here’s an example, with fake syntax and a newline added to make it easier to distinguish the result groups:

Note that timestamps are only ordered within a group of records; “I’m heading to bed” was sent before “what did you want to play later?” but the “Waterdeep” rows are ordered correctly.


The only way I can think of to do this is with 2n + 1 queries:

  1. SELECT message_id, conversation_id, sent_micros FROM messages WHERE message_plain LIKE '%Waterdeep%' ORDER BY sent_micros ASC
  2. For each row in that result:
    • SELECT * FROM messages WHERE conversation_id = :conversation_id AND sent_micros >= :sent_micros ORDER BY sent_micros ASC LIMIT 4
    • SELECT * FROM messages WHERE conversation_id = :conversation_id AND sent_micros <= :sent_micros ORDER BY sent_micros DESC LIMIT 4

but this seems very wasteful and inefficient.

Is there a better way to handle this? Could window functions be useful? Would a different database engine help?


It seems likely that at some point I’ll add full-text search capability rather than simple LIKE-based matching. I imagine this will basically just give the message_id results for a query, so it feels like some kind of “return n rows around primary key values x, y, z” solution would be ideal. The LIKE-based query can be decomposed into that form, and would only be two queries rather than 2n + 1.

Advertisement

Answer

You can do it with ROW_NUMBER() window function:

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement