Skip to content

Commit

Permalink
Add support of Elasticsearch Token Filters (#16843)
Browse files Browse the repository at this point in the history
Co-authored-by: Hisham Bin Ateya <[email protected]>
  • Loading branch information
denispetrische and hishamco authored Oct 17, 2024
1 parent a7620c6 commit 99c8b77
Show file tree
Hide file tree
Showing 8 changed files with 563 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -432,14 +432,15 @@ public async Task<ActionResult> ForceDelete(ElasticIndexSettingsViewModel model)
return RedirectToAction(nameof(Index));
}

public async Task<IActionResult> Mappings(string indexName)
public async Task<IActionResult> IndexInfo(string indexName)
{
var mappings = await _elasticIndexManager.GetIndexMappings(indexName);
var formattedJson = JNode.Parse(mappings).ToJsonString(JOptions.Indented);
return View(new MappingsViewModel
var info = await _elasticIndexManager.GetIndexInfo(indexName);

var formattedJson = JNode.Parse(info).ToJsonString(JOptions.Indented);
return View(new IndexInfoViewModel
{
IndexName = _elasticIndexManager.GetFullIndexName(indexName),
Mappings = formattedJson
IndexInfo = formattedJson
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using Microsoft.Extensions.Configuration;
using OrchardCore.Environment.Shell.Configuration;

namespace OrchardCore.Search.Elasticsearch;

internal static class ElasticsearchOptionsExtensions
{
internal static ElasticsearchOptions AddAnalyzers(this ElasticsearchOptions options, IConfigurationSection configuration)
{
var jsonNode = configuration.GetSection(nameof(options.Analyzers)).AsJsonNode();
var jsonElement = JsonSerializer.Deserialize<JsonElement>(jsonNode);

var analyzersObject = JsonObject.Create(jsonElement, new JsonNodeOptions()
{
PropertyNameCaseInsensitive = true,
});

if (analyzersObject is not null)
{
if (jsonNode is JsonObject jAnalyzers)
{
foreach (var analyzer in jAnalyzers)
{
if (analyzer.Value is not JsonObject jAnalyzer)
{
continue;
}

options.Analyzers.Add(analyzer.Key, jAnalyzer);
}
}
}

if (options.Analyzers.Count == 0)
{
// When no analyzers are configured, we'll define a default analyzer.
options.Analyzers.Add(ElasticsearchConstants.DefaultAnalyzer, new JsonObject
{
["type"] = ElasticsearchConstants.DefaultAnalyzer,
});
}

return options;
}

internal static ElasticsearchOptions AddFilter(this ElasticsearchOptions options, IConfigurationSection configuration)
{
var jsonNode = configuration.GetSection(nameof(options.Filter)).AsJsonNode();
var jsonElement = JsonSerializer.Deserialize<JsonElement>(jsonNode);

var filterObject = JsonObject.Create(jsonElement, new JsonNodeOptions()
{
PropertyNameCaseInsensitive = true,
});

if (filterObject is not null)
{
if (jsonNode is JsonObject jFilters)
{
foreach (var filter in jFilters)
{
if (filter.Value is not JsonObject jFilter)
{
continue;
}

options.Filter.Add(filter.Key, jFilter);
}
}
}

return options;
}

internal static ElasticsearchOptions AddIndexPrefix(this ElasticsearchOptions options, IConfigurationSection configuration)
{
options.IndexPrefix = configuration.GetValue<string>(nameof(options.IndexPrefix));

return options;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,42 +54,9 @@ public override void ConfigureServices(IServiceCollection services)
{
var configuration = _shellConfiguration.GetSection(ElasticConnectionOptionsConfigurations.ConfigSectionName);
o.IndexPrefix = configuration.GetValue<string>(nameof(o.IndexPrefix));
var jsonNode = configuration.GetSection(nameof(o.Analyzers)).AsJsonNode();
var jsonElement = JsonSerializer.Deserialize<JsonElement>(jsonNode);
var analyzersObject = JsonObject.Create(jsonElement, new JsonNodeOptions()
{
PropertyNameCaseInsensitive = true,
});
if (analyzersObject != null)
{
o.IndexPrefix = configuration.GetValue<string>(nameof(o.IndexPrefix));
if (jsonNode is JsonObject jAnalyzers)
{
foreach (var analyzer in jAnalyzers)
{
if (analyzer.Value is not JsonObject jAnalyzer)
{
continue;
}
o.Analyzers.Add(analyzer.Key, jAnalyzer);
}
}
}
if (o.Analyzers.Count == 0)
{
// When no analyzers are configured, we'll define a default analyzer.
o.Analyzers.Add(ElasticsearchConstants.DefaultAnalyzer, new JsonObject
{
["type"] = ElasticsearchConstants.DefaultAnalyzer,
});
}
o.AddIndexPrefix(configuration);
o.AddFilter(configuration);
o.AddAnalyzers(configuration);
});

services.AddElasticServices();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
namespace OrchardCore.Search.Elasticsearch.ViewModels;

public class MappingsViewModel
public class IndexInfoViewModel
{
public string IndexName { get; set; }
public string Mappings { get; set; }
public string IndexInfo { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
<p>@entry.AnalyzerName</p>
</div>
<div class="float-end">
<a asp-action="Mappings" asp-route-IndexName="@entry.Name" class="btn btn-primary btn-sm">@T["Mappings"]</a>
<a asp-action="IndexInfo" asp-route-IndexName="@entry.Name" class="btn btn-primary btn-sm">@T["Index Info"]</a>
<a asp-action="Query" asp-route-IndexName="@entry.Name" class="btn btn-success btn-sm">@T["Query"]</a>
<a asp-action="Reset" asp-route-id="@entry.Name" class="btn btn-primary btn-sm" data-title="@T["Reset Index"]" data-message="@T["This will restart the indexing of all content items. Continue?"]" data-ok-text="@T["Yes"]" data-cancel-text="@T["No"]" data-ok-class="btn-primary" data-url-af="UnsafeUrl">@T["Reset"]</a>
<a asp-action="Rebuild" asp-route-id="@entry.Name" class="btn btn-warning btn-sm" data-title="@T["Rebuild Index"]" data-message="@T["Your index will be rebuilt, which might alter some services during the process. Continue?"]" data-ok-text="@T["Yes"]" data-cancel-text="@T["No"]" data-url-af="UnsafeUrl">@T["Rebuild"]</a>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
@model MappingsViewModel
@model IndexInfoViewModel

<h2>@T["Elasticsearch index mappings"]</h2>
<h2>@T["Elasticsearch index information"]</h2>

<div class="row">
<div class="col">
<div class="mb-4">
<label asp-for="Mappings" class="form-label">@T["Mappings for: "]@Model.IndexName</label>
<label asp-for="IndexInfo" class="form-label">@T["Info for: "]@Model.IndexName</label>
<div class="form-control" style="min-height: 400px;">
<div id="@Html.IdFor(x => x.Mappings)_editor" style="min-height: 385px;" dir="@Orchard.CultureDir()" data-schema='@Model.Mappings'></div>
<div id="@Html.IdFor(x => x.IndexInfo)_editor" style="min-height: 385px;" dir="@Orchard.CultureDir()" data-schema='@Model.IndexInfo'></div>
</div>
<textarea asp-for="Mappings" hidden></textarea>
<span class="hint">@T["The Elasticsearch index mapping. For reference only."]</span>
<textarea asp-for="IndexInfo" hidden></textarea>
<span class="hint">@T["The Elasticsearch index information. For reference only."]</span>
</div>
</div>
</div>
Expand All @@ -35,8 +35,8 @@
setTheme();
var modelUri = monaco.Uri.parse("x://orchardcore.search.elastic.mappings.json");
var editor = document.getElementById('@Html.IdFor(x => x.Mappings)_editor');
var textArea = document.getElementById('@Html.IdFor(x => x.Mappings)');
var editor = document.getElementById('@Html.IdFor(x => x.IndexInfo)_editor');
var textArea = document.getElementById('@Html.IdFor(x => x.IndexInfo)');
var schema = JSON.parse(editor.dataset.schema)
var model = monaco.editor.createModel(textArea.value, "json", modelUri);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ public class ElasticsearchOptions
public string IndexPrefix { get; set; }

public Dictionary<string, JsonObject> Analyzers { get; } = [];

public Dictionary<string, JsonObject> Filter { get; } = [];
}
Loading

0 comments on commit 99c8b77

Please sign in to comment.