/** * Return the score for the given suggestion (number between 0 to 1). * In case the suggestion should not be added return -1. */ static double SpellCheck_GetScore(SpellCheckCtx *scCtx, char *suggestion, size_t len, t_fieldMask fieldMask) { RedisModuleKey *keyp = NULL; InvertedIndex *invidx = Redis_OpenInvertedIndexEx(scCtx->sctx, suggestion, len, 0, &keyp); double retVal = 0; if (!invidx) { // can not find inverted index key, score is 0. goto end; } IndexReader *reader = NewTermIndexReader(invidx, NULL, fieldMask, NULL, 1); IndexIterator *iter = NewReadIterator(reader); RSIndexResult *r; if (iter->Read(iter->ctx, &r) != INDEXREAD_EOF) { // we have at least one result, the suggestion is relevant. if (scCtx->fullScoreInfo) { retVal = invidx->numDocs; } else { retVal = invidx->numDocs; } } else { // fieldMask has filtered all docs, this suggestions should not be returned retVal = -1; } ReadIterator_Free(iter); end: if (keyp) { RedisModule_CloseKey(keyp); } return retVal; }
IndexIterator *query_EvalLoadStage(Query *q, QueryStage *stage) { // if there's only one word in the query and no special field filtering, // we can just use the optimized score index int isSingleWord = q->numTokens == 1 && q->fieldMask == 0xff && q->root->nchildren == 1; IndexReader *ir = Redis_OpenReader(q->ctx, stage->value, strlen(stage->value), q->docTable, isSingleWord, q->fieldMask); if (ir == NULL) { return NULL; } return NewReadIterator(ir); }
/* Open an index reader to iterate a tag index for a specific tag. Used at query evaluation time. * Returns NULL if there is no such tag in the index */ IndexIterator *TagIndex_OpenReader(TagIndex *idx, IndexSpec *sp, const char *value, size_t len, double weight) { InvertedIndex *iv = TrieMap_Find(idx->values, (char *)value, len); if (iv == TRIEMAP_NOTFOUND || !iv) { return NULL; } RSToken tok = {.str = (char *)value, .len = len}; RSQueryTerm *t = NewQueryTerm(&tok, 0); IndexReader *r = NewTermIndexReader(iv, sp, RS_FIELDMASK_ALL, t, weight); if (!r) { return NULL; } return NewReadIterator(r); } /* Format the key name for a tag index */ RedisModuleString *TagIndex_FormatName(RedisSearchCtx *sctx, const char *field) { return RedisModule_CreateStringPrintf(sctx->redisCtx, TAG_INDEX_KEY_FMT, sctx->spec->name, field); } static TagIndex *openTagKeyDict(RedisSearchCtx *ctx, RedisModuleString *key, int openWrite) { KeysDictValue *kdv = dictFetchValue(ctx->spec->keysDict, key); if (kdv) { return kdv->p; } if (!openWrite) { return NULL; } kdv = calloc(1, sizeof(*kdv)); kdv->p = NewTagIndex(); kdv->dtor = TagIndex_Free; dictAdd(ctx->spec->keysDict, key, kdv); return kdv->p; }