Commit 40ed8d7b authored by Nick Craver's avatar Nick Craver

Cleanup: NRediSearch client

parent 17a6ced7
// .NET port of https://github.com/RedisLabs/JRediSearch/ // .NET port of https://github.com/RedisLabs/JRediSearch/
using StackExchange.Redis; using StackExchange.Redis;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
...@@ -27,19 +26,20 @@ public enum IndexOptions ...@@ -27,19 +26,20 @@ public enum IndexOptions
/// </summary> /// </summary>
KeepFieldFlags = 2, KeepFieldFlags = 2,
/// <summary> /// <summary>
/// The default indexing options - use term offsets and keep fields flags
/// </summary>
Default = UseTermOffsets | KeepFieldFlags,
/// <summary>
/// If set, we keep an index of the top entries per term, allowing extremely fast single word queries /// If set, we keep an index of the top entries per term, allowing extremely fast single word queries
/// regardless of index size, at the cost of more memory /// regardless of index size, at the cost of more memory
/// </summary> /// </summary>
UseScoreIndexes = 4, UseScoreIndexes = 4,
/// <summary> /// <summary>
/// The default indexing options - use term offsets and keep fields flags
/// </summary>
Default = UseTermOffsets | KeepFieldFlags ,
/// <summary>
/// If set, we will disable the Stop-Words completely /// If set, we will disable the Stop-Words completely
/// </summary> /// </summary>
DisableStopWords = 8 DisableStopWords = 8
} }
private static void SerializeRedisArgs(IndexOptions flags, List<object> args) private static void SerializeRedisArgs(IndexOptions flags, List<object> args)
{ {
if ((flags & IndexOptions.UseTermOffsets) == 0) if ((flags & IndexOptions.UseTermOffsets) == 0)
...@@ -60,6 +60,7 @@ private static void SerializeRedisArgs(IndexOptions flags, List<object> args) ...@@ -60,6 +60,7 @@ private static void SerializeRedisArgs(IndexOptions flags, List<object> args)
args.Add(0); args.Add(0);
} }
} }
private readonly IDatabaseAsync _db; private readonly IDatabaseAsync _db;
private IDatabase DbSync private IDatabase DbSync
=> (_db as IDatabase) ?? throw new InvalidOperationException("Synchronous operations are not available on this database instance"); => (_db as IDatabase) ?? throw new InvalidOperationException("Synchronous operations are not available on this database instance");
...@@ -71,6 +72,7 @@ public Client(RedisKey indexName, IDatabaseAsync db) ...@@ -71,6 +72,7 @@ public Client(RedisKey indexName, IDatabaseAsync db)
_db = db ?? throw new ArgumentNullException(nameof(db)); _db = db ?? throw new ArgumentNullException(nameof(db));
_boxedIndexName = indexName; // only box once, not per-command _boxedIndexName = indexName; // only box once, not per-command
} }
public Client(RedisKey indexName, IDatabase db) : this(indexName, (IDatabaseAsync)db) { } public Client(RedisKey indexName, IDatabase db) : this(indexName, (IDatabaseAsync)db) { }
/// <summary> /// <summary>
...@@ -81,9 +83,10 @@ public Client(RedisKey indexName, IDatabaseAsync db) ...@@ -81,9 +83,10 @@ public Client(RedisKey indexName, IDatabaseAsync db)
/// <returns>true if successful</returns> /// <returns>true if successful</returns>
public bool CreateIndex(Schema schema, IndexOptions options) public bool CreateIndex(Schema schema, IndexOptions options)
{ {
var args = new List<object>(); var args = new List<object>
{
args.Add(_boxedIndexName); _boxedIndexName
};
SerializeRedisArgs(options, args); SerializeRedisArgs(options, args);
args.Add("SCHEMA".Literal()); args.Add("SCHEMA".Literal());
...@@ -103,9 +106,10 @@ public bool CreateIndex(Schema schema, IndexOptions options) ...@@ -103,9 +106,10 @@ public bool CreateIndex(Schema schema, IndexOptions options)
/// <returns>true if successful</returns> /// <returns>true if successful</returns>
public async Task<bool> CreateIndexAsync(Schema schema, IndexOptions options) public async Task<bool> CreateIndexAsync(Schema schema, IndexOptions options)
{ {
var args = new List<object>(); var args = new List<object>
{
args.Add(_boxedIndexName); _boxedIndexName
};
SerializeRedisArgs(options, args); SerializeRedisArgs(options, args);
args.Add("SCHEMA".Literal()); args.Add("SCHEMA".Literal());
...@@ -124,8 +128,10 @@ public async Task<bool> CreateIndexAsync(Schema schema, IndexOptions options) ...@@ -124,8 +128,10 @@ public async Task<bool> CreateIndexAsync(Schema schema, IndexOptions options)
/// <returns>a <see cref="SearchResult"/> object with the results</returns> /// <returns>a <see cref="SearchResult"/> object with the results</returns>
public SearchResult Search(Query q) public SearchResult Search(Query q)
{ {
var args = new List<object>(); var args = new List<object>
args.Add(_boxedIndexName); {
_boxedIndexName
};
q.SerializeRedisArgs(args); q.SerializeRedisArgs(args);
var resp = (RedisResult[])DbSync.Execute("FT.SEARCH", args); var resp = (RedisResult[])DbSync.Execute("FT.SEARCH", args);
...@@ -139,8 +145,10 @@ public SearchResult Search(Query q) ...@@ -139,8 +145,10 @@ public SearchResult Search(Query q)
/// <returns>a <see cref="SearchResult"/> object with the results</returns> /// <returns>a <see cref="SearchResult"/> object with the results</returns>
public async Task<SearchResult> SearchAsync(Query q) public async Task<SearchResult> SearchAsync(Query q)
{ {
var args = new List<object>(); var args = new List<object>
args.Add(_boxedIndexName); {
_boxedIndexName
};
q.SerializeRedisArgs(args); q.SerializeRedisArgs(args);
var resp = (RedisResult[])await _db.ExecuteAsync("FT.SEARCH", args).ConfigureAwait(false); var resp = (RedisResult[])await _db.ExecuteAsync("FT.SEARCH", args).ConfigureAwait(false);
...@@ -152,25 +160,16 @@ public async Task<SearchResult> SearchAsync(Query q) ...@@ -152,25 +160,16 @@ public async Task<SearchResult> SearchAsync(Query q)
/// </summary> /// </summary>
/// <param name="fieldName">TAG field name</param> /// <param name="fieldName">TAG field name</param>
/// <returns>List of TAG field values</returns> /// <returns>List of TAG field values</returns>
public RedisValue[] TagVals(string fieldName) public RedisValue[] TagVals(string fieldName) =>
{ (RedisValue[])DbSync.Execute("FT.TAGVALS", _boxedIndexName, fieldName);
var resp = (RedisValue[])DbSync.Execute("FT.TAGVALS", _boxedIndexName, fieldName);
return resp;
}
/// <summary> /// <summary>
/// Return Distinct Values in a TAG field /// Return Distinct Values in a TAG field
/// </summary> /// </summary>
/// <param name="fieldName">TAG field name</param> /// <param name="fieldName">TAG field name</param>
/// <returns>List of TAG field values</returns> /// <returns>List of TAG field values</returns>
public async Task<RedisValue[]> TagValsAsync(string fieldName) public async Task<RedisValue[]> TagValsAsync(string fieldName) =>
{ (RedisValue[])await _db.ExecuteAsync("FT.TAGVALS", _boxedIndexName, fieldName).ConfigureAwait(false);
var resp = (RedisValue[])await _db.ExecuteAsync("FT.TAGVALS", _boxedIndexName, fieldName).ConfigureAwait(false);
return resp;
}
/// <summary> /// <summary>
/// Add a single document to the query /// Add a single document to the query
...@@ -230,14 +229,22 @@ private List<object> BuildAddDocumentArgs(string docId, Dictionary<string, Redis ...@@ -230,14 +229,22 @@ private List<object> BuildAddDocumentArgs(string docId, Dictionary<string, Redis
} }
/// <summary> /// <summary>
/// replaceDocument is a convenience for calling addDocument with replace=true /// Convenience method for calling AddDocument with replace=true.
/// </summary> /// </summary>
/// <param name="docId">The ID of the document to replce.</param>
/// <param name="fields">The document fields.</param>
/// <param name="score">The new score.</param>
/// <param name="payload">The new payload.</param>
public bool ReplaceDocument(string docId, Dictionary<string, RedisValue> fields, double score = 1.0, byte[] payload = null) public bool ReplaceDocument(string docId, Dictionary<string, RedisValue> fields, double score = 1.0, byte[] payload = null)
=> AddDocument(docId, fields, score, false, true, payload); => AddDocument(docId, fields, score, false, true, payload);
/// <summary> /// <summary>
/// replaceDocument is a convenience for calling addDocument with replace=true /// Convenience method for calling AddDocumentAsync with replace=true.
/// </summary> /// </summary>
/// <param name="docId">The ID of the document to replce.</param>
/// <param name="fields">The document fields.</param>
/// <param name="score">The new score.</param>
/// <param name="payload">The new payload.</param>
public Task<bool> ReplaceDocumentAsync(string docId, Dictionary<string, RedisValue> fields, double score = 1.0, byte[] payload = null) public Task<bool> ReplaceDocumentAsync(string docId, Dictionary<string, RedisValue> fields, double score = 1.0, byte[] payload = null)
=> AddDocumentAsync(docId, fields, score, false, true, payload); => AddDocumentAsync(docId, fields, score, false, true, payload);
...@@ -279,20 +286,18 @@ public async Task<bool> AddHashAsync(string docId, double score, bool replace) ...@@ -279,20 +286,18 @@ public async Task<bool> AddHashAsync(string docId, double score, bool replace)
/// </summary> /// </summary>
/// <remarks>TODO: Make a class for easier access to the index properties</remarks> /// <remarks>TODO: Make a class for easier access to the index properties</remarks>
/// <returns>a map of key/value pairs</returns> /// <returns>a map of key/value pairs</returns>
public Dictionary<string, RedisValue> GetInfo() public Dictionary<string, RedisValue> GetInfo() =>
{ ParseGetInfo(DbSync.Execute("FT.INFO", _boxedIndexName));
return ParseGetInfo(DbSync.Execute("FT.INFO", _boxedIndexName));
}
/// <summary> /// <summary>
/// Get the index info, including memory consumption and other statistics. /// Get the index info, including memory consumption and other statistics.
/// </summary> /// </summary>
/// <remarks>TODO: Make a class for easier access to the index properties</remarks> /// <remarks>TODO: Make a class for easier access to the index properties</remarks>
/// <returns>a map of key/value pairs</returns> /// <returns>a map of key/value pairs</returns>
public async Task<Dictionary<string, RedisValue>> GetInfoAsync() public async Task<Dictionary<string, RedisValue>> GetInfoAsync() =>
{ ParseGetInfo(await _db.ExecuteAsync("FT.INFO", _boxedIndexName).ConfigureAwait(false));
return ParseGetInfo(await _db.ExecuteAsync("FT.INFO", _boxedIndexName).ConfigureAwait(false));
} private static Dictionary<string, RedisValue> ParseGetInfo(RedisResult value)
static Dictionary<string, RedisValue> ParseGetInfo(RedisResult value)
{ {
var res = (RedisValue[])value; var res = (RedisValue[])value;
var info = new Dictionary<string, RedisValue>(); var info = new Dictionary<string, RedisValue>();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment