Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add federated multisearch to MeilisearchClient #571

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
MEILISEARCH_VERSION=v1.9.0
MEILISEARCH_VERSION=v1.10.0
PROXIED_MEILISEARCH=http://nginx/api/
MEILISEARCH_URL=http://meilisearch:7700
13 changes: 13 additions & 0 deletions src/Meilisearch/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
using System.Text.Json;
using System.Text.Json.Serialization;

using Meilisearch.Converters;

namespace Meilisearch
{
/// <summary>
/// This class adds some defaults to work with Meilisearch client.
/// </summary>
internal static class Constants
{
/// <summary>
/// JsonSerializer options used when serializing objects that needs to remove null values.
/// </summary>
internal static readonly JsonSerializerOptions FederatedSearchJsonSerializerOptionsRemoveNulls =
new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = { new MultiSearchFederationOptionsConverter() }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just add the converter as an annotation?

};

/// <summary>
/// JsonSerializer options used when serializing objects that needs to remove null values.
/// </summary>
Expand Down
73 changes: 73 additions & 0 deletions src/Meilisearch/Converters/AlwaysIncludeEmptyObjectConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Meilisearch.Converters
{
/// <summary>
/// Always include property in json. MultiSearchFederationOptions will be serialized as "{}"
///
/// </summary>
/// <typeparam name="T"></typeparam>

Check warning on line 13 in src/Meilisearch/Converters/AlwaysIncludeEmptyObjectConverter.cs

View workflow job for this annotation

GitHub Actions / integration-tests

XML comment has a typeparam tag for 'T', but there is no type parameter by that name

Check warning on line 13 in src/Meilisearch/Converters/AlwaysIncludeEmptyObjectConverter.cs

View workflow job for this annotation

GitHub Actions / integration-tests

XML comment has a typeparam tag for 'T', but there is no type parameter by that name
public class MultiSearchFederationOptionsConverter : JsonConverter<MultiSearchFederationOptions>
{
public override MultiSearchFederationOptions Read(ref Utf8JsonReader reader, Type typeToConvert,
JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<MultiSearchFederationOptions>(ref reader, options);
}

public override void Write(Utf8JsonWriter writer, MultiSearchFederationOptions value,
JsonSerializerOptions options)
{
if (value == null || !HasAnyValueSet(value))
{
WriteEmptyObject(writer);
}
else
{
var sanitizedOptions =
RemoveSelfFromSerializerOptions(options); //Prevents getting stuck in a loop during serialization
JsonSerializer.Serialize(writer, value, sanitizedOptions);
}
}

private static JsonSerializerOptions RemoveSelfFromSerializerOptions(JsonSerializerOptions options)
{
var sanitizedOptions = new JsonSerializerOptions(options);
sanitizedOptions.Converters.Remove(sanitizedOptions.Converters.First(c =>
c.GetType() == typeof(MultiSearchFederationOptionsConverter)));
return sanitizedOptions;
}

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;
}
}
}
35 changes: 35 additions & 0 deletions src/Meilisearch/FederatedMultiSearchQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;

using Meilisearch.Converters;

namespace Meilisearch
{
/// <summary>
/// Search query used in federated multi-index search
/// </summary>
public class FederatedMultiSearchQuery
{
/// <summary>
/// Default constructor that ensures FederationOptions are always set
/// </summary>
public FederatedMultiSearchQuery()
{
FederationOptions = new MultiSearchFederationOptions();
}

/// <summary>
/// The queries
/// </summary>
[JsonPropertyName("queries")]
public List<FederatedSearchQuery> Queries { get; set; }

/// <summary>
/// The federated search query options
/// </summary>
[JsonInclude]
[JsonPropertyName("federation")]
[JsonConverter(typeof(MultiSearchFederationOptionsConverter))]
public MultiSearchFederationOptions FederationOptions { get; set; }
}
}
16 changes: 16 additions & 0 deletions src/Meilisearch/FederatedSearchQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Text.Json.Serialization;

namespace Meilisearch
{
/// <summary>
/// Search query for federated multi-index search
/// </summary>
public class FederatedSearchQuery : SearchQueryBase
{
/// <summary>
/// Federated search options
/// </summary>
[JsonPropertyName("federationOptions")]
public MultiSearchFederationOptions FederationOptions { get; set; }
}
}
1 change: 0 additions & 1 deletion src/Meilisearch/Meilisearch.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
<PackageIcon>logo.png</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseExpression>MIT</PackageLicenseExpression>

<GenerateDocumentationFile>True</GenerateDocumentationFile>
<!-- Warnings for missing XML documentation are only visible during dev time -->
<!-- You may want to remove the NoWarn node in case documentation will be mandatory in the future -->
Expand Down
Loading
Loading