nostrdb: query: implement profile search query plans
The basic idea of this is to allow you to use the standard
nip50 query interface to search for profiles using our profile
index.
query: {"search":"jb55", "kinds":[0]}
will result in a profile_search query plan that searches kind0 profiles
for the corresponding `name` or `display_name`.
Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
committed by
Daniel D’Aquino
parent
9cff8608f6
commit
0b8090cb28
@@ -239,6 +239,7 @@ enum ndb_query_plan {
|
||||
NDB_PLAN_TAGS,
|
||||
NDB_PLAN_SEARCH,
|
||||
NDB_PLAN_RELAY_KINDS,
|
||||
NDB_PLAN_PROFILE_SEARCH,
|
||||
};
|
||||
|
||||
// A id + u64 + timestamp
|
||||
@@ -4027,6 +4028,67 @@ next:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ndb_query_plan_execute_profile_search(
|
||||
struct ndb_txn *txn,
|
||||
struct ndb_filter *filter,
|
||||
struct ndb_query_results *results,
|
||||
int limit)
|
||||
{
|
||||
const char *search;
|
||||
int i;
|
||||
|
||||
// The filter pubkey is updated inplace for each note search
|
||||
unsigned char *filter_pubkey;
|
||||
unsigned char pubkey[32] = {0};
|
||||
struct ndb_filter_elements *els;
|
||||
struct ndb_search profile_search;
|
||||
struct ndb_filter note_filter, *f = ¬e_filter;
|
||||
|
||||
if (!(search = ndb_filter_find_search(filter)))
|
||||
return 0;
|
||||
|
||||
if (!ndb_filter_init_with(f, 1))
|
||||
return 0;
|
||||
|
||||
ndb_filter_start_field(f, NDB_FILTER_KINDS);
|
||||
ndb_filter_add_int_element(f, 0);
|
||||
ndb_filter_end_field(f);
|
||||
|
||||
ndb_filter_start_field(f, NDB_FILTER_AUTHORS);
|
||||
ndb_filter_add_id_element(f, pubkey);
|
||||
ndb_filter_end_field(f);
|
||||
ndb_filter_end(f);
|
||||
|
||||
// get the authors element after we finalize the filter, since
|
||||
// the data could have moved
|
||||
if (!(els = ndb_filter_find_elements(f, NDB_FILTER_AUTHORS)))
|
||||
return 0;
|
||||
|
||||
// grab pointer to pubkey in the filter so that we can
|
||||
// update the filter as we go
|
||||
if (!(filter_pubkey = ndb_filter_get_id_element(f, els, 0)))
|
||||
return 0;
|
||||
|
||||
for (i = 0; !query_is_full(results, limit); i++) {
|
||||
if (i == 0) {
|
||||
if (!ndb_search_profile(txn, &profile_search, search))
|
||||
break;
|
||||
} else {
|
||||
if (!ndb_search_profile_next(&profile_search))
|
||||
break;
|
||||
}
|
||||
|
||||
// Copy pubkey into filter
|
||||
memcpy(filter_pubkey, profile_search.key->id, 32);
|
||||
|
||||
// Look up the corresponding note associated with that pubkey
|
||||
if (!ndb_query_plan_execute_author_kinds(txn, f, results, limit))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ndb_query_plan_execute_relay_kinds(
|
||||
struct ndb_txn *txn,
|
||||
struct ndb_filter *filter,
|
||||
@@ -4239,6 +4301,11 @@ static enum ndb_query_plan ndb_filter_plan(struct ndb_filter *filter)
|
||||
tags = ndb_filter_find_elements(filter, NDB_FILTER_TAGS);
|
||||
relays = ndb_filter_find_elements(filter, NDB_FILTER_RELAYS);
|
||||
|
||||
// profile search
|
||||
if (kinds && kinds->count == 1 && kinds->elements[0] == 0 && search) {
|
||||
return NDB_PLAN_PROFILE_SEARCH;
|
||||
}
|
||||
|
||||
// this is rougly similar to the heuristic in strfry's dbscan
|
||||
if (search) {
|
||||
return NDB_PLAN_SEARCH;
|
||||
@@ -4270,6 +4337,7 @@ static const char *ndb_query_plan_name(enum ndb_query_plan plan_id)
|
||||
case NDB_PLAN_AUTHORS: return "authors";
|
||||
case NDB_PLAN_RELAY_KINDS: return "relay_kinds";
|
||||
case NDB_PLAN_AUTHOR_KINDS: return "author_kinds";
|
||||
case NDB_PLAN_PROFILE_SEARCH: return "profile_search";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
@@ -4308,6 +4376,12 @@ static int ndb_query_filter(struct ndb_txn *txn, struct ndb_filter *filter,
|
||||
if (!ndb_query_plan_execute_search(txn, filter, &results, limit))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case NDB_PLAN_PROFILE_SEARCH:
|
||||
if (!ndb_query_plan_execute_profile_search(txn, filter, &results, limit))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
// We have just kinds, just scan the kind index
|
||||
case NDB_PLAN_KINDS:
|
||||
if (!ndb_query_plan_execute_kinds(txn, filter, &results, limit))
|
||||
|
||||
Reference in New Issue
Block a user