diff --git a/.env b/.env
index 767307bf..e1107443 100644
--- a/.env
+++ b/.env
@@ -1,3 +1,3 @@
-MEILISEARCH_VERSION=v1.9.0
+MEILISEARCH_VERSION=v1.10.0
PROXIED_MEILISEARCH=http://nginx/api/
MEILISEARCH_URL=http://meilisearch:7700
diff --git a/src/Meilisearch/Constants.cs b/src/Meilisearch/Constants.cs
index 5aa0a1b3..9410ea12 100644
--- a/src/Meilisearch/Constants.cs
+++ b/src/Meilisearch/Constants.cs
@@ -1,6 +1,8 @@
using System.Text.Json;
using System.Text.Json.Serialization;
+using Meilisearch.Converters;
+
namespace Meilisearch
{
///
diff --git a/src/Meilisearch/Converters/AlwaysIncludeEmptyObjectConverter.cs b/src/Meilisearch/Converters/AlwaysIncludeEmptyObjectConverter.cs
new file mode 100644
index 00000000..6c2342a4
--- /dev/null
+++ b/src/Meilisearch/Converters/AlwaysIncludeEmptyObjectConverter.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Linq;
+using System.Reflection;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Meilisearch.Converters
+{
+ ///
+ /// Always include property in json. MultiSearchFederationOptions will be serialized as "{}"
+ ///
+ public class MultiSearchFederationOptionsConverter : JsonConverter
+ {
+ ///
+ /// Would override the default read logic, but here we use the default
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override MultiSearchFederationOptions Read(ref Utf8JsonReader reader, Type typeToConvert,
+ JsonSerializerOptions options)
+ {
+ return JsonSerializer.Deserialize(ref reader, options);
+ }
+
+ ///
+ /// Write json for MultiSearchFederationOptions and include it always as empty object
+ ///
+ ///
+ ///
+ ///
+ public override void Write(Utf8JsonWriter writer, MultiSearchFederationOptions value,
+ JsonSerializerOptions options)
+ {
+ if (value == null || !HasAnyValueSet(value))
+ {
+ WriteEmptyObject(writer);
+ }
+ else
+ {
+ JsonSerializer.Serialize(writer, value);
+ }
+ }
+ private static void WriteEmptyObject(Utf8JsonWriter writer)
+ {
+ writer.WriteStartObject();
+ writer.WriteEndObject();
+ }
+
+ private bool HasAnyValueSet(MultiSearchFederationOptions value)
+ {
+ foreach (var property in
+ value.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
+ {
+ var propertyValue = property.GetValue(value);
+ var defaultValue = GetDefaultValue(property.PropertyType);
+
+ if (!Equals(propertyValue, defaultValue))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private object GetDefaultValue(Type type)
+ {
+ return type.IsValueType ? Activator.CreateInstance(type) : null;
+ }
+ }
+}
diff --git a/src/Meilisearch/FederatedMultiSearchQuery.cs b/src/Meilisearch/FederatedMultiSearchQuery.cs
new file mode 100644
index 00000000..35e57af3
--- /dev/null
+++ b/src/Meilisearch/FederatedMultiSearchQuery.cs
@@ -0,0 +1,35 @@
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+using Meilisearch.Converters;
+
+namespace Meilisearch
+{
+ ///
+ /// Search query used in federated multi-index search
+ ///
+ public class FederatedMultiSearchQuery
+ {
+ ///
+ /// Default constructor that ensures FederationOptions are always set
+ ///
+ public FederatedMultiSearchQuery()
+ {
+ FederationOptions = new MultiSearchFederationOptions();
+ }
+
+ ///
+ /// The queries
+ ///
+ [JsonPropertyName("queries")]
+ public List Queries { get; set; }
+
+ ///
+ /// The federated search query options
+ ///
+ [JsonInclude]
+ [JsonPropertyName("federation")]
+ [JsonConverter(typeof(MultiSearchFederationOptionsConverter))]
+ public MultiSearchFederationOptions FederationOptions { get; set; }
+ }
+}
diff --git a/src/Meilisearch/FederatedSearchQuery.cs b/src/Meilisearch/FederatedSearchQuery.cs
new file mode 100644
index 00000000..45a24fbd
--- /dev/null
+++ b/src/Meilisearch/FederatedSearchQuery.cs
@@ -0,0 +1,16 @@
+using System.Text.Json.Serialization;
+
+namespace Meilisearch
+{
+ ///
+ /// Search query for federated multi-index search
+ ///
+ public class FederatedSearchQuery : SearchQueryBase
+ {
+ ///
+ /// Federated search options
+ ///
+ [JsonPropertyName("federationOptions")]
+ public MultiSearchFederationOptions FederationOptions { get; set; }
+ }
+}
diff --git a/src/Meilisearch/Meilisearch.csproj b/src/Meilisearch/Meilisearch.csproj
index e13645d9..d15f2245 100644
--- a/src/Meilisearch/Meilisearch.csproj
+++ b/src/Meilisearch/Meilisearch.csproj
@@ -13,7 +13,6 @@
logo.png
README.md
MIT
-
True
diff --git a/src/Meilisearch/MeilisearchClient.cs b/src/Meilisearch/MeilisearchClient.cs
index c926da86..c4be414b 100644
--- a/src/Meilisearch/MeilisearchClient.cs
+++ b/src/Meilisearch/MeilisearchClient.cs
@@ -13,7 +13,6 @@
namespace Meilisearch
{
-
///
/// Typed client for Meilisearch.
///
@@ -29,7 +28,9 @@ public class MeilisearchClient
///
/// URL corresponding to Meilisearch server.
/// API Key to connect to the Meilisearch server.
- public MeilisearchClient(string url, string apiKey = default) : this(new HttpClient(new MeilisearchMessageHandler(new HttpClientHandler())) { BaseAddress = url.ToSafeUri() }, apiKey)
+ public MeilisearchClient(string url, string apiKey = default) : this(
+ new HttpClient(new MeilisearchMessageHandler(new HttpClientHandler())) { BaseAddress = url.ToSafeUri() },
+ apiKey)
{
}
@@ -58,7 +59,8 @@ public async Task GetVersionAsync(CancellationToken cancella
{
var response = await _http.GetAsync("version", cancellationToken).ConfigureAwait(false);
- return await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
+ return await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken)
+ .ConfigureAwait(false);
}
///
@@ -75,23 +77,47 @@ public Index Index(string uid)
}
///
- /// Searches multiple indexes at once
+ /// Searches multiple indexes at once but gets an aggregated list of results.
+ ///
+ /// The query to be executed (must have at least one query inside)
+ ///
+ /// Aggregated results.
+ ///
+ public async Task> FederatedMultiSearchAsync(FederatedMultiSearchQuery query,
+ CancellationToken cancellationToken = default)
+ {
+ if (!query.Queries.TrueForAll(x => x.IndexUid != null))
+ {
+ throw new ArgumentNullException("IndexUid", "IndexUid should be provided for all search queries");
+ }
+
+ var responseMessage = await _http.PostAsJsonAsync("multi-search", query,
+ Constants.JsonSerializerOptionsRemoveNulls, cancellationToken: cancellationToken);
+ return await responseMessage.Content
+ .ReadFromJsonAsync>(cancellationToken: cancellationToken)
+ .ConfigureAwait(false);
+ }
+
+ ///
+ /// Searches multiple indexes at once.
///
/// The queries to be executed (must have IndexUid set)
///
///
///
- public async Task MultiSearchAsync(MultiSearchQuery query, CancellationToken cancellationToken = default)
+ public async Task MultiSearchAsync(MultiSearchQuery query,
+ CancellationToken cancellationToken = default)
{
if (!query.Queries.TrueForAll(x => x.IndexUid != null))
{
throw new ArgumentNullException("IndexUid", "IndexUid should be provided for all search queries");
}
- var responseMessage = await _http.PostAsJsonAsync("multi-search", query, Constants.JsonSerializerOptionsRemoveNulls, cancellationToken: cancellationToken);
+ var responseMessage = await _http.PostAsJsonAsync("multi-search", query,
+ Constants.JsonSerializerOptionsRemoveNulls, cancellationToken: cancellationToken);
return await responseMessage.Content
- .ReadFromJsonAsync(cancellationToken: cancellationToken)
- .ConfigureAwait(false);
+ .ReadFromJsonAsync(cancellationToken: cancellationToken)
+ .ConfigureAwait(false);
}
///
@@ -101,13 +127,16 @@ public async Task MultiSearchAsync(MultiSearchQuery query, Ca
/// Primary key for documents.
/// The cancellation token for this call.
/// Returns the associated task.
- public async Task CreateIndexAsync(string uid, string primaryKey = default, CancellationToken cancellationToken = default)
+ public async Task CreateIndexAsync(string uid, string primaryKey = default,
+ CancellationToken cancellationToken = default)
{
var index = new Index(uid, primaryKey);
- var responseMessage = await _http.PostJsonCustomAsync("indexes", index, Constants.JsonSerializerOptionsRemoveNulls, cancellationToken: cancellationToken)
+ var responseMessage = await _http.PostJsonCustomAsync("indexes", index,
+ Constants.JsonSerializerOptionsRemoveNulls, cancellationToken: cancellationToken)
.ConfigureAwait(false);
- return await responseMessage.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
+ return await responseMessage.Content.ReadFromJsonAsync(cancellationToken: cancellationToken)
+ .ConfigureAwait(false);
}
///
@@ -117,7 +146,8 @@ public async Task CreateIndexAsync(string uid, string primaryKey = def
/// Primary key set.
/// The cancellation token for this call.
/// Returns the associated task.
- public async Task UpdateIndexAsync(string uid, string primarykeytoChange, CancellationToken cancellationToken = default)
+ public async Task UpdateIndexAsync(string uid, string primarykeytoChange,
+ CancellationToken cancellationToken = default)
{
return await Index(uid).UpdateAsync(primarykeytoChange, cancellationToken).ConfigureAwait(false);
}
@@ -140,7 +170,8 @@ public async Task DeleteIndexAsync(string uid, CancellationToken cance
/// Query parameters. Supports limit and offset.
/// The cancellation token for this call.
/// An IEnumerable of indexes in JsonElement format.
- public async Task GetAllRawIndexesAsync(IndexesQuery query = default, CancellationToken cancellationToken = default)
+ public async Task GetAllRawIndexesAsync(IndexesQuery query = default,
+ CancellationToken cancellationToken = default)
{
var uri = query.ToQueryString(uri: "indexes");
var response = await _http.GetAsync(uri, cancellationToken).ConfigureAwait(false);
@@ -155,12 +186,15 @@ public async Task GetAllRawIndexesAsync(IndexesQuery query = defau
/// Query parameters. Supports limit and offset.
/// The cancellation token for this call.
/// Return Enumerable of Index.
- public async Task>> GetAllIndexesAsync(IndexesQuery query = default, CancellationToken cancellationToken = default)
+ public async Task>> GetAllIndexesAsync(IndexesQuery query = default,
+ CancellationToken cancellationToken = default)
{
var uri = query.ToQueryString(uri: "indexes");
var response = await _http.GetAsync(uri, cancellationToken).ConfigureAwait(false);
- var content = await response.Content.ReadFromJsonAsync>>(cancellationToken: cancellationToken).ConfigureAwait(false);
+ var content = await response.Content
+ .ReadFromJsonAsync>>(cancellationToken: cancellationToken)
+ .ConfigureAwait(false);
content.Results
.Select(p => p.WithHttpClient(_http))
.ToList();
@@ -188,7 +222,7 @@ public async Task GetIndexAsync(string uid, CancellationToken cancellatio
public async Task GetRawIndexAsync(string uid, CancellationToken cancellationToken = default)
{
var json = await (
- await Meilisearch.Index.GetRawAsync(_http, uid, cancellationToken).ConfigureAwait(false))
+ await Meilisearch.Index.GetRawAsync(_http, uid, cancellationToken).ConfigureAwait(false))
.Content.ReadAsStringAsync().ConfigureAwait(false);
return JsonDocument.Parse(json).RootElement;
}
@@ -199,7 +233,8 @@ await Meilisearch.Index.GetRawAsync(_http, uid, cancellationToken).ConfigureAwai
/// Query parameters supports by the method.
/// The cancellation token for this call.
/// Returns a list of tasks.
- public async Task>> GetTasksAsync(TasksQuery query = default, CancellationToken cancellationToken = default)
+ public async Task>> GetTasksAsync(TasksQuery query = default,
+ CancellationToken cancellationToken = default)
{
return await TaskEndpoint().GetTasksAsync(query, cancellationToken).ConfigureAwait(false);
}
@@ -229,7 +264,8 @@ public async Task WaitForTaskAsync(
int intervalMs = 50,
CancellationToken cancellationToken = default)
{
- return await TaskEndpoint().WaitForTaskAsync(taskUid, timeoutMs, intervalMs, cancellationToken).ConfigureAwait(false);
+ return await TaskEndpoint().WaitForTaskAsync(taskUid, timeoutMs, intervalMs, cancellationToken)
+ .ConfigureAwait(false);
}
///
@@ -239,7 +275,8 @@ public async Task WaitForTaskAsync(
/// Returns stats of all indexes.
public async Task GetStatsAsync(CancellationToken cancellationToken = default)
{
- return await _http.GetFromJsonAsync("stats", cancellationToken: cancellationToken).ConfigureAwait(false);
+ return await _http.GetFromJsonAsync("stats", cancellationToken: cancellationToken)
+ .ConfigureAwait(false);
}
///
@@ -281,7 +318,8 @@ public async Task CreateDumpAsync(CancellationToken cancellationToken
{
var response = await _http.PostAsync("dumps", default, cancellationToken).ConfigureAwait(false);
- return await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
+ return await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken)
+ .ConfigureAwait(false);
}
///
@@ -301,10 +339,12 @@ public async Task CreateSnapshotAsync(CancellationToken cancellationTo
/// Query parameters supports by the method.
/// The cancellation token for this call.
/// Returns a list of the API keys.
- public async Task>> GetKeysAsync(KeysQuery query = default, CancellationToken cancellationToken = default)
+ public async Task>> GetKeysAsync(KeysQuery query = default,
+ CancellationToken cancellationToken = default)
{
var uri = query.ToQueryString(uri: "keys");
- return await _http.GetFromJsonAsync>>(uri, cancellationToken: cancellationToken)
+ return await _http
+ .GetFromJsonAsync>>(uri, cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
@@ -329,10 +369,12 @@ public async Task GetKeyAsync(string keyOrUid, CancellationToken cancellati
public async Task CreateKeyAsync(Key keyOptions, CancellationToken cancellationToken = default)
{
var responseMessage =
- await _http.PostAsJsonAsync("keys", keyOptions, Constants.JsonSerializerOptionsWriteNulls, cancellationToken: cancellationToken)
+ await _http.PostAsJsonAsync("keys", keyOptions, Constants.JsonSerializerOptionsWriteNulls,
+ cancellationToken: cancellationToken)
.ConfigureAwait(false);
- return await responseMessage.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
+ return await responseMessage.Content.ReadFromJsonAsync(cancellationToken: cancellationToken)
+ .ConfigureAwait(false);
}
///
@@ -341,7 +383,8 @@ await _http.PostAsJsonAsync("keys", keyOptions, Constants.JsonSerializerOptionsW
/// Query parameters supports by the method.
/// The cancellation token for this call.
/// Returns the task info of finished task.
- public async Task CancelTasksAsync(CancelTasksQuery query, CancellationToken cancellationToken = default)
+ public async Task CancelTasksAsync(CancelTasksQuery query,
+ CancellationToken cancellationToken = default)
{
return await TaskEndpoint().CancelTasksAsync(query, cancellationToken).ConfigureAwait(false);
}
@@ -352,7 +395,8 @@ public async Task CancelTasksAsync(CancelTasksQuery query, Cancellatio
/// Query parameters supports by the method.
/// The cancellation token for this call.
/// Returns the task info of finished task.
- public async Task DeleteTasksAsync(DeleteTasksQuery query, CancellationToken cancellationToken = default)
+ public async Task DeleteTasksAsync(DeleteTasksQuery query,
+ CancellationToken cancellationToken = default)
{
return await TaskEndpoint().DeleteTasksAsync(query, cancellationToken).ConfigureAwait(false);
}
@@ -365,19 +409,18 @@ public async Task DeleteTasksAsync(DeleteTasksQuery query, Cancellatio
/// A name to label the key internally.
/// The cancellation token for this call.
/// Returns the updated API key.
- public async Task UpdateKeyAsync(string keyOrUid, string description = null, string name = null, CancellationToken cancellationToken = default)
+ public async Task UpdateKeyAsync(string keyOrUid, string description = null, string name = null,
+ CancellationToken cancellationToken = default)
{
- var key = new Key
- {
- Name = name,
- Description = description
- };
+ var key = new Key { Name = name, Description = description };
var responseMessage =
- await _http.PatchAsJsonAsync($"keys/{keyOrUid}", key, Constants.JsonSerializerOptionsRemoveNulls, cancellationToken: cancellationToken)
+ await _http.PatchAsJsonAsync($"keys/{keyOrUid}", key, Constants.JsonSerializerOptionsRemoveNulls,
+ cancellationToken: cancellationToken)
.ConfigureAwait(false);
- return await responseMessage.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
+ return await responseMessage.Content.ReadFromJsonAsync(cancellationToken: cancellationToken)
+ .ConfigureAwait(false);
}
///
@@ -399,12 +442,15 @@ public async Task DeleteKeyAsync(string keyOrUid, CancellationToken cancel
/// List of IndexSwap objects.
/// The cancellation token for this call.
/// Returns the task info of finished task.
- public async Task SwapIndexesAsync(List indexes, CancellationToken cancellationToken = default)
+ public async Task SwapIndexesAsync(List indexes,
+ CancellationToken cancellationToken = default)
{
- var response = await _http.PostAsJsonAsync("swap-indexes", indexes, Constants.JsonSerializerOptionsRemoveNulls, cancellationToken: cancellationToken)
- .ConfigureAwait(false);
+ var response = await _http.PostAsJsonAsync("swap-indexes", indexes,
+ Constants.JsonSerializerOptionsRemoveNulls, cancellationToken: cancellationToken)
+ .ConfigureAwait(false);
- return await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
+ return await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken)
+ .ConfigureAwait(false);
}
///
@@ -417,7 +463,8 @@ public async Task SwapIndexesAsync(List indexes, Cancellati
/// When there is no defined in the client or as argument.
/// When the sent param is in the past
/// Returns a generated tenant token.
- public string GenerateTenantToken(string apiKeyUid, TenantTokenRules searchRules, string apiKey = null, DateTime? expiresAt = null)
+ public string GenerateTenantToken(string apiKeyUid, TenantTokenRules searchRules, string apiKey = null,
+ DateTime? expiresAt = null)
{
return TenantToken.GenerateToken(apiKeyUid, searchRules, apiKey ?? ApiKey, expiresAt);
}
@@ -436,6 +483,5 @@ private TaskEndpoint TaskEndpoint()
return _taskEndpoint;
}
-
}
}
diff --git a/src/Meilisearch/MultiSearchFederationOptions.cs b/src/Meilisearch/MultiSearchFederationOptions.cs
new file mode 100644
index 00000000..e07a70d1
--- /dev/null
+++ b/src/Meilisearch/MultiSearchFederationOptions.cs
@@ -0,0 +1,25 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+using Meilisearch.Converters;
+
+namespace Meilisearch
+{
+ ///
+ /// Federation options in federated multi-index search
+ ///
+ public class MultiSearchFederationOptions
+ {
+ ///
+ /// Number of documents to skip
+ ///
+ [JsonPropertyName("offset")]
+ public int Offset { get; set; }
+
+ ///
+ /// Maximum number of documents returned
+ ///
+ [JsonPropertyName("limit")]
+ public int Limit { get; set; }
+ }
+}
diff --git a/src/Meilisearch/SearchQuery.cs b/src/Meilisearch/SearchQuery.cs
index fcfcbf19..a4de0e48 100644
--- a/src/Meilisearch/SearchQuery.cs
+++ b/src/Meilisearch/SearchQuery.cs
@@ -1,4 +1,3 @@
-using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace Meilisearch
@@ -6,110 +5,8 @@ namespace Meilisearch
///
/// Search Query for Meilisearch class.
///
- public class SearchQuery
+ public class SearchQuery : SearchQueryBase
{
- ///
- /// The id of the index
- ///
- [JsonPropertyName("indexUid")]
- public string IndexUid { get; set; }
-
- ///
- /// Gets or sets query string.
- ///
- [JsonPropertyName("q")]
- public string Q { get; set; }
-
- ///
- /// Gets or sets the filter to apply to the query.
- ///
- [JsonPropertyName("filter")]
- public dynamic Filter { get; set; }
-
- ///
- /// Gets or sets attributes to retrieve.
- ///
- [JsonPropertyName("attributesToRetrieve")]
- public IEnumerable AttributesToRetrieve { get; set; }
-
- ///
- /// Gets or sets attributes to crop.
- ///
- [JsonPropertyName("attributesToCrop")]
- public IEnumerable AttributesToCrop { get; set; }
-
- ///
- /// Gets or sets attributes to search on.
- ///
- [JsonPropertyName("attributesToSearchOn")]
- public IEnumerable AttributesToSearchOn { get; set; }
-
- ///
- /// Gets or sets length used to crop field values.
- ///
- [JsonPropertyName("cropLength")]
- public int? CropLength { get; set; }
-
- ///
- /// Gets or sets attributes to highlight.
- ///
- [JsonPropertyName("attributesToHighlight")]
- public IEnumerable AttributesToHighlight { get; set; }
-
- ///
- /// Gets or sets the crop marker to apply before and/or after cropped part selected within an attribute defined in `attributesToCrop` parameter.
- ///
- [JsonPropertyName("cropMarker")]
- public string CropMarker { get; set; }
-
- ///
- /// Gets or sets the tag to put before the highlighted query terms.
- ///
- [JsonPropertyName("highlightPreTag")]
- public string HighlightPreTag { get; set; }
-
- ///
- /// Gets or sets the tag to put after the highlighted query terms.
- ///
- [JsonPropertyName("highlightPostTag")]
- public string HighlightPostTag { get; set; }
-
- ///
- /// Gets or sets the facets for the query.
- ///
- [JsonPropertyName("facets")]
- public IEnumerable Facets { get; set; }
-
- ///
- /// Gets or sets showMatchesPosition. It defines whether an object that contains information about the matches should be returned or not.
- ///
- [JsonPropertyName("showMatchesPosition")]
- public bool? ShowMatchesPosition { get; set; }
-
- ///
- /// Gets or sets the sorted attributes.
- ///
- [JsonPropertyName("sort")]
- public IEnumerable Sort { get; set; }
-
- ///
- /// Gets or sets the words matching strategy.
- ///
- [JsonPropertyName("matchingStrategy")]
- public string MatchingStrategy { get; set; }
-
- ///
- /// Gets or sets showRankingScore parameter. It defines wheter the global ranking score of a document (between 0 and 1) is returned or not.
- ///
- [JsonPropertyName("showRankingScore")]
- public bool? ShowRankingScore { get; set; }
-
- ///
- /// Gets or sets showRankingScoreDetails parameter. It defines whether details on how the ranking score was computed are returned or not.
- ///
- [JsonPropertyName("showRankingScoreDetails")]
- public bool? ShowRankingScoreDetails { get; set; }
-
// pagination:
///
diff --git a/src/Meilisearch/SearchQueryBase.cs b/src/Meilisearch/SearchQueryBase.cs
new file mode 100644
index 00000000..ca2ce0c1
--- /dev/null
+++ b/src/Meilisearch/SearchQueryBase.cs
@@ -0,0 +1,113 @@
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+namespace Meilisearch
+{
+ ///
+ /// Base properties of search query
+ ///
+ public class SearchQueryBase
+ {
+ ///
+ /// The id of the index
+ ///
+ [JsonPropertyName("indexUid")]
+ public string IndexUid { get; set; }
+
+ ///
+ /// Gets or sets query string.
+ ///
+ [JsonPropertyName("q")]
+ public string Q { get; set; }
+
+ ///
+ /// Gets or sets the filter to apply to the query.
+ ///
+ [JsonPropertyName("filter")]
+ public dynamic Filter { get; set; }
+
+ ///
+ /// Gets or sets attributes to retrieve.
+ ///
+ [JsonPropertyName("attributesToRetrieve")]
+ public IEnumerable AttributesToRetrieve { get; set; }
+
+ ///
+ /// Gets or sets attributes to crop.
+ ///
+ [JsonPropertyName("attributesToCrop")]
+ public IEnumerable AttributesToCrop { get; set; }
+
+ ///
+ /// Gets or sets attributes to search on.
+ ///
+ [JsonPropertyName("attributesToSearchOn")]
+ public IEnumerable AttributesToSearchOn { get; set; }
+
+ ///
+ /// Gets or sets length used to crop field values.
+ ///
+ [JsonPropertyName("cropLength")]
+ public int? CropLength { get; set; }
+
+ ///
+ /// Gets or sets attributes to highlight.
+ ///
+ [JsonPropertyName("attributesToHighlight")]
+ public IEnumerable AttributesToHighlight { get; set; }
+
+ ///
+ /// Gets or sets the crop marker to apply before and/or after cropped part selected within an attribute defined in `attributesToCrop` parameter.
+ ///
+ [JsonPropertyName("cropMarker")]
+ public string CropMarker { get; set; }
+
+ ///
+ /// Gets or sets the tag to put before the highlighted query terms.
+ ///
+ [JsonPropertyName("highlightPreTag")]
+ public string HighlightPreTag { get; set; }
+
+ ///
+ /// Gets or sets the tag to put after the highlighted query terms.
+ ///
+ [JsonPropertyName("highlightPostTag")]
+ public string HighlightPostTag { get; set; }
+
+ ///
+ /// Gets or sets the facets for the query.
+ ///
+ [JsonPropertyName("facets")]
+ public IEnumerable Facets { get; set; }
+
+ ///
+ /// Gets or sets showMatchesPosition. It defines whether an object that contains information about the matches should be returned or not.
+ ///
+ [JsonPropertyName("showMatchesPosition")]
+ public bool? ShowMatchesPosition { get; set; }
+
+ ///
+ /// Gets or sets the sorted attributes.
+ ///
+ [JsonPropertyName("sort")]
+ public IEnumerable Sort { get; set; }
+
+ ///
+ /// Gets or sets the words matching strategy.
+ ///
+ [JsonPropertyName("matchingStrategy")]
+ public string MatchingStrategy { get; set; }
+
+ ///
+ /// Gets or sets showRankingScore parameter. It defines whether the global ranking score of a document (between 0 and 1) is returned or not.
+ ///
+ [JsonPropertyName("showRankingScore")]
+ public bool? ShowRankingScore { get; set; }
+
+ ///
+ /// Gets or sets showRankingScoreDetails parameter. It defines whether details on how the ranking score was computed are returned or not.
+ ///
+ [JsonPropertyName("showRankingScoreDetails")]
+ public bool? ShowRankingScoreDetails { get; set; }
+ }
+}
diff --git a/tests/Meilisearch.Tests/Datasets.cs b/tests/Meilisearch.Tests/Datasets.cs
index 610454a2..d4ae2155 100644
--- a/tests/Meilisearch.Tests/Datasets.cs
+++ b/tests/Meilisearch.Tests/Datasets.cs
@@ -55,7 +55,6 @@ sealed class UnixEpochDateTimeConverter : JsonConverter
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
-
var unixTime = reader.GetInt64();
return s_epoch.AddMilliseconds(unixTime);
}
diff --git a/tests/Meilisearch.Tests/MultiIndexSearchTests.cs b/tests/Meilisearch.Tests/MultiIndexSearchTests.cs
index e5101ab0..9daeb4b6 100644
--- a/tests/Meilisearch.Tests/MultiIndexSearchTests.cs
+++ b/tests/Meilisearch.Tests/MultiIndexSearchTests.cs
@@ -31,7 +31,8 @@ public async Task InitializeAsync()
_index2 = await _fixture.SetUpBasicIndex("BasicIndex-MultiSearch-Index2");
var t1 = _index1.UpdateFilterableAttributesAsync(new[] { "genre" });
var t2 = _index2.UpdateFilterableAttributesAsync(new[] { "genre" });
- await Task.WhenAll((await Task.WhenAll(t1, t2)).Select(x => _fixture.DefaultClient.WaitForTaskAsync(x.TaskUid)));
+ await Task.WhenAll(
+ (await Task.WhenAll(t1, t2)).Select(x => _fixture.DefaultClient.WaitForTaskAsync(x.TaskUid)));
}
[Fact]
@@ -40,7 +41,7 @@ public async Task BasicSearch()
var result = await _fixture.DefaultClient.MultiSearchAsync(new MultiSearchQuery()
{
Queries = new System.Collections.Generic.List()
- {
+ {
new SearchQuery() { IndexUid = _index1.Uid, Q = "", Filter = "genre = 'SF'" },
new SearchQuery() { IndexUid = _index2.Uid, Q = "", Filter = "genre = 'Action'" }
}
@@ -77,5 +78,65 @@ Movie GetMovie(IEnumerable movies, string id)
return og.Name == x.Name && og.Genre == x.Genre;
}).Should().BeTrue();
}
+
+
+ [Fact]
+ public async Task FederatedSearchWithNoFederationOptions()
+ {
+ var result = await _fixture.DefaultClient.FederatedMultiSearchAsync(
+ new FederatedMultiSearchQuery()
+ {
+ Queries = new List()
+ {
+ new FederatedSearchQuery() { IndexUid = _index1.Uid, Q = "", Filter = "genre = 'SF'" },
+ new FederatedSearchQuery()
+ {
+ IndexUid = _index2.Uid, Q = "", Filter = "genre = 'Action'"
+ }
+ },
+ });
+
+ result.Hits.Should().HaveCount(4);
+ }
+
+ [Fact]
+ public async Task FederatedSearchWithEmptyOptions()
+ {
+ var result = await _fixture.DefaultClient.FederatedMultiSearchAsync(
+ new FederatedMultiSearchQuery()
+ {
+ Queries = new List()
+ {
+ new FederatedSearchQuery() { IndexUid = _index1.Uid, Q = "", Filter = "genre = 'SF'" },
+ new FederatedSearchQuery()
+ {
+ IndexUid = _index2.Uid, Q = "", Filter = "genre = 'Action'"
+ }
+ },
+ FederationOptions = new MultiSearchFederationOptions() { }
+ });
+
+ result.Hits.Should().HaveCount(4);
+ }
+
+ [Fact]
+ public async Task FederatedSearchWithLimitAndOffset()
+ {
+ var federatedquer = new FederatedMultiSearchQuery()
+ {
+ Queries = new List()
+ {
+ new FederatedSearchQuery() { IndexUid = _index1.Uid, Q = "", Filter = "genre = 'SF'" },
+ new FederatedSearchQuery() { IndexUid = _index2.Uid, Q = "", Filter = "genre = 'Action'" }
+ },
+ FederationOptions = new MultiSearchFederationOptions() { Limit = 2, Offset = 0 }
+ };
+ var result = await _fixture.DefaultClient.FederatedMultiSearchAsync(federatedquer
+ );
+
+ var testJson = JsonSerializer.Serialize(federatedquer);
+
+ result.Hits.Should().HaveCount(2);
+ }
}
}