About nostr database
I’ve been reading the `NostrDatabase` trait and its LMDB backend in rust-nostr. Storing events is simple—just put `(event_id → event)` in a KV store. The challenge is querying, since LMDB itself only supports very basic lookups.
The approach in nostr-lmdb is to build extra indexes (e.g. author+kind+created_at+id, tag+created_at+id, etc.). Queries pick the most suitable index to fetch candidate event IDs, then filter them one by one.
A few thoughts:
Indexing on a KV store is straightforward, nothing mystical.
The query logic is verbose, basically a hand-rolled rule-based optimizer. A cost-based optimizer might be a more advanced path?
NostrDatabase only supports a single filter, while the protocol allows multiple filters (OR across filters). So a relay must merge results manually.
#rust-nostr #nostr
关于 nostr database
最近读了 rust-nostr 里的 NostrDatabase trait 及其 lmdb 实现。存储部分很直观,以 event_id 为 key 存储 event。难点在查询:因为 lmdb 只是 KV 数据库,它本身不支持复杂查询。
nostr-lmdb 的做法,是在存储 event 的同时,额外维护多组索引(比如 author+kind+created_at+id,tag+created_at+id 等)。查询时,先挑合适的索引定位可能的 event id,再逐一过滤。
这种实现让我有几点感受:
原来在 KV 底层上建索引可以这么做,其实没什么玄妙。
查询逻辑比较冗长,感觉像是手工实现了一个 rule-based 优化器。如果更复杂,或许需要 cost-based 优化?
目前 NostrDatabase 只支持单一 filter,而协议里 filter 之间是 OR 关系。如果要做 relay,还得额外处理多个 filter 的合并。
