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_TAGS,
|
||||||
NDB_PLAN_SEARCH,
|
NDB_PLAN_SEARCH,
|
||||||
NDB_PLAN_RELAY_KINDS,
|
NDB_PLAN_RELAY_KINDS,
|
||||||
|
NDB_PLAN_PROFILE_SEARCH,
|
||||||
};
|
};
|
||||||
|
|
||||||
// A id + u64 + timestamp
|
// A id + u64 + timestamp
|
||||||
@@ -4027,6 +4028,67 @@ next:
|
|||||||
return 1;
|
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(
|
static int ndb_query_plan_execute_relay_kinds(
|
||||||
struct ndb_txn *txn,
|
struct ndb_txn *txn,
|
||||||
struct ndb_filter *filter,
|
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);
|
tags = ndb_filter_find_elements(filter, NDB_FILTER_TAGS);
|
||||||
relays = ndb_filter_find_elements(filter, NDB_FILTER_RELAYS);
|
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
|
// this is rougly similar to the heuristic in strfry's dbscan
|
||||||
if (search) {
|
if (search) {
|
||||||
return NDB_PLAN_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_AUTHORS: return "authors";
|
||||||
case NDB_PLAN_RELAY_KINDS: return "relay_kinds";
|
case NDB_PLAN_RELAY_KINDS: return "relay_kinds";
|
||||||
case NDB_PLAN_AUTHOR_KINDS: return "author_kinds";
|
case NDB_PLAN_AUTHOR_KINDS: return "author_kinds";
|
||||||
|
case NDB_PLAN_PROFILE_SEARCH: return "profile_search";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "unknown";
|
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))
|
if (!ndb_query_plan_execute_search(txn, filter, &results, limit))
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
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
|
// We have just kinds, just scan the kind index
|
||||||
case NDB_PLAN_KINDS:
|
case NDB_PLAN_KINDS:
|
||||||
if (!ndb_query_plan_execute_kinds(txn, filter, &results, limit))
|
if (!ndb_query_plan_execute_kinds(txn, filter, &results, limit))
|
||||||
|
|||||||
Reference in New Issue
Block a user