Skip to content

Add federated multisearch to MeilisearchClient #571

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

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 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
2 changes: 2 additions & 0 deletions src/Meilisearch/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Text.Json;
using System.Text.Json.Serialization;

using Meilisearch.Converters;

namespace Meilisearch
{
/// <summary>
Expand Down
72 changes: 72 additions & 0 deletions src/Meilisearch/Converters/AlwaysIncludeEmptyObjectConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
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>
public class MultiSearchFederationOptionsConverter : JsonConverter<MultiSearchFederationOptions>
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't see what problem does this converter solve

Copy link
Author

Choose a reason for hiding this comment

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

The API requiers a empty "federation" object when calling the /multisearch endpoint this is to respond in the expected format:

{
  "hits": [ ...],
  "processingTimeMs": 4,
  "limit": 20,
  "offset": 0,
  "estimatedTotalHits": 11
}

When the empty object parameter is not included it responds in a totaly different way:

{
  "results": [
    {
      "indexUid": "searchIndex1",
      "hits": [...],
      "query": "w",
      "processingTimeMs": 4,
      "limit": 20,
      "offset": 0,
      "estimatedTotalHits": 11
    },
    {
      "indexUid": "searchIndex2",
      "hits": [...],
      "query": "w",
      "processingTimeMs": 0,
      "limit": 20,
      "offset": 0,
      "estimatedTotalHits": 0
    },
    {
      "indexUid": "searchIndex3",
      "hits": [...],
      "query": "w",
      "processingTimeMs": 0,
      "limit": 20,
      "offset": 0,
      "estimatedTotalHits": 0
    }
  ]
}

{
/// <summary>
/// Would override the default read logic, but here we use the default
/// </summary>
/// <param name="reader"></param>
/// <param name="typeToConvert"></param>
/// <param name="options"></param>
/// <returns></returns>
public override MultiSearchFederationOptions Read(ref Utf8JsonReader reader, Type typeToConvert,
JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<MultiSearchFederationOptions>(ref reader, options);
}

/// <summary>
/// Write json for MultiSearchFederationOptions and include it always as empty object
/// </summary>
/// <param name="writer"></param>
/// <param name="value"></param>
/// <param name="options"></param>
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;
}
}
}
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