Skip to content

Commit

Permalink
Fix AzureAI Search issues (#16093)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeAlhayek authored May 19, 2024
1 parent c5acb34 commit 21d2a70
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,11 @@ public async Task<IActionResult> EditPost(AzureAISettingsViewModel model)
settings.IndexedContentTypes = model.IndexedContentTypes;
settings.Culture = model.Culture ?? string.Empty;

if (string.IsNullOrEmpty(settings.IndexFullName))
{
settings.IndexFullName = _indexManager.GetFullIndexName(settings.IndexName);
}

if (string.IsNullOrEmpty(settings.AnalyzerName))
{
settings.AnalyzerName = AzureAISearchDefaultOptions.DefaultAnalyzer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ public override async Task<IDisplayResult> EditAsync(ContentPartFieldDefinition
return null;
}

return Initialize<AzureAISearchContentIndexSettings>("AzureAISearchContentIndexSettings_Edit", model => contentPartFieldDefinition.GetSettings<AzureAISearchContentIndexSettings>())
.Location("Content:10");
return Initialize<AzureAISearchContentIndexSettings>("AzureAISearchContentIndexSettings_Edit", model =>
{
model.Included = contentPartFieldDefinition.GetSettings<AzureAISearchContentIndexSettings>().Included;
}).Location("Content:10");
}

public override async Task<IDisplayResult> UpdateAsync(ContentPartFieldDefinition contentPartFieldDefinition, UpdatePartFieldEditorContext context)
Expand All @@ -33,11 +35,11 @@ public override async Task<IDisplayResult> UpdateAsync(ContentPartFieldDefinitio
return null;
}

var model = new AzureAISearchContentIndexSettings();
var settings = new AzureAISearchContentIndexSettings();

await context.Updater.TryUpdateModelAsync(model, Prefix);
await context.Updater.TryUpdateModelAsync(settings, Prefix);

context.Builder.WithSettings(model);
context.Builder.WithSettings(settings);

return await EditAsync(contentPartFieldDefinition, context.Updater);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ public override async Task<IDisplayResult> EditAsync(ContentTypePartDefinition c
return null;
}

return Initialize<AzureAISearchContentIndexSettings>("AzureAISearchContentIndexSettings_Edit", model => contentTypePartDefinition.GetSettings<AzureAISearchContentIndexSettings>())
.Location("Content:10");
return Initialize<AzureAISearchContentIndexSettings>("AzureAISearchContentIndexSettings_Edit", model =>
{
model.Included = contentTypePartDefinition.GetSettings<AzureAISearchContentIndexSettings>().Included;
}).Location("Content:10");
}

public override async Task<IDisplayResult> UpdateAsync(ContentTypePartDefinition contentTypePartDefinition, UpdateTypePartEditorContext context)
Expand All @@ -33,11 +35,11 @@ public override async Task<IDisplayResult> UpdateAsync(ContentTypePartDefinition
return null;
}

var model = new AzureAISearchContentIndexSettings();
var settings = new AzureAISearchContentIndexSettings();

await context.Updater.TryUpdateModelAsync(model, Prefix);
await context.Updater.TryUpdateModelAsync(settings, Prefix);

context.Builder.WithSettings(model);
context.Builder.WithSettings(settings);

return await EditAsync(contentTypePartDefinition, context.Updater);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using OrchardCore.Deployment;
using OrchardCore.Search.AzureAI.Deployment.Models;
using OrchardCore.Search.AzureAI.Models;
using OrchardCore.Search.AzureAI.Services;

Expand All @@ -14,33 +14,45 @@ public class AzureAISearchIndexDeploymentSource(AzureAISearchIndexSettingsServic

public async Task ProcessDeploymentStepAsync(DeploymentStep step, DeploymentPlanResult result)
{
if (step is not AzureAISearchIndexDeploymentStep settingsStep)
if (step is not AzureAISearchIndexDeploymentStep indexStep)
{
return;
}

var indexSettings = await _indexSettingsService.GetSettingsAsync();

var data = new JsonArray();
var indicesToAdd = settingsStep.IncludeAll ? indexSettings.Select(x => x.IndexName).ToArray() : settingsStep.IndexNames;
var indicesToAdd = indexStep.IncludeAll
? indexSettings.Select(x => x.IndexName).ToArray()
: indexStep.IndexNames;

foreach (var index in indexSettings)
{
if (indicesToAdd.Contains(index.IndexName))
if (index.IndexName == null || !indicesToAdd.Contains(index.IndexName))
{
var indexSettingsDict = new Dictionary<string, AzureAISearchIndexSettings>
{
{ index.IndexName, index },
};

data.Add(JObject.FromObject(indexSettingsDict));
continue;
}

var indexInfo = GetIndexInfo(index);

data.Add(JObject.FromObject(indexInfo));
}

result.Steps.Add(new JsonObject
{
["name"] = nameof(AzureAISearchIndexSettings),
["name"] = step.Name,
["Indices"] = data,
});
}

private static AzureAISearchIndexInfo GetIndexInfo(AzureAISearchIndexSettings settings)
=> new()
{
IndexName = settings.IndexName,
AnalyzerName = settings.AnalyzerName,
QueryAnalyzerName = settings.QueryAnalyzerName,
IndexedContentTypes = settings.IndexedContentTypes ?? [],
IndexLatest = settings.IndexLatest,
Culture = settings.Culture,
};
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using OrchardCore.Deployment;
using OrchardCore.Search.AzureAI.Recipes;

namespace OrchardCore.Search.AzureAI.Deployment;

public class AzureAISearchIndexDeploymentStep : DeploymentStep
{
public AzureAISearchIndexDeploymentStep()
{
Name = "AzureAISearchIndexSettings";
Name = AzureAISearchIndexSettingsStep.Name;
}

public bool IncludeAll { get; set; } = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace OrchardCore.Search.AzureAI.Deployment.Models;

public class AzureAISearchIndexInfo
{
public string IndexName { get; set; }

public string AnalyzerName { get; set; }

public string QueryAnalyzerName { get; set; }

public bool IndexLatest { get; set; }

public string[] IndexedContentTypes { get; set; }

public string Culture { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;

namespace OrchardCore.Search.AzureAI.Models;

public class AzureAISearchIndexSettings
{
[JsonIgnore]
public string IndexName { get; set; }

[JsonIgnore]
public string IndexFullName { get; set; }

public string AnalyzerName { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using OrchardCore.Recipes.Models;
using OrchardCore.Recipes.Services;
using OrchardCore.Search.AzureAI.Deployment;
using OrchardCore.Search.AzureAI.Deployment.Models;
using OrchardCore.Search.AzureAI.Models;
using OrchardCore.Search.AzureAI.Services;

Expand Down Expand Up @@ -46,23 +47,45 @@ public async Task ExecuteAsync(RecipeExecutionContext context)
return;
}

var indexNames = new List<string>();
var newIndexNames = new List<string>();

foreach (var index in indexes)
{
var indexSettings = index.ToObject<AzureAISearchIndexSettings>();
var indexInfo = index.ToObject<AzureAISearchIndexInfo>();

if (!AzureAISearchIndexNamingHelper.TryGetSafeIndexName(indexSettings.IndexName, out var indexName))
if (string.IsNullOrWhiteSpace(indexInfo.IndexName))
{
_logger.LogError("Invalid index name was provided in the recipe step. IndexName: {indexName}.", indexSettings.IndexName);
_logger.LogError("No index name was provided in the '{Name}' recipe step.", Name);

continue;
}

indexSettings.IndexName = indexName;
if (!AzureAISearchIndexNamingHelper.TryGetSafeIndexName(indexInfo.IndexName, out var indexName))
{
_logger.LogError("Invalid index name was provided in the recipe step. IndexName: {IndexName}.", indexInfo.IndexName);

continue;
}

if (!await _indexManager.ExistsAsync(indexSettings.IndexName))
if (indexInfo.IndexedContentTypes?.Length == 0)
{
_logger.LogError("No {IndexedContentTypes} were provided in the recipe step. IndexName: {IndexName}.", nameof(indexInfo.IndexedContentTypes), indexInfo.IndexName);

continue;
}

if (!await _indexManager.ExistsAsync(indexInfo.IndexName))
{
var indexSettings = new AzureAISearchIndexSettings()
{
IndexName = indexInfo.IndexName,
AnalyzerName = indexInfo.AnalyzerName,
QueryAnalyzerName = indexInfo.QueryAnalyzerName,
IndexedContentTypes = indexInfo.IndexedContentTypes,
IndexLatest = indexInfo.IndexLatest,
Culture = indexInfo.Culture,
};

if (string.IsNullOrWhiteSpace(indexSettings.AnalyzerName))
{
indexSettings.AnalyzerName = AzureAISearchDefaultOptions.DefaultAnalyzer;
Expand All @@ -73,22 +96,14 @@ public async Task ExecuteAsync(RecipeExecutionContext context)
indexSettings.QueryAnalyzerName = indexSettings.AnalyzerName;
}

if (indexSettings.IndexedContentTypes == null || indexSettings.IndexedContentTypes.Length == 0)
{
_logger.LogError("No {fieldName} were provided in the recipe step. IndexName: {indexName}.", nameof(indexSettings.IndexedContentTypes), indexSettings.IndexName);

continue;
}

indexSettings.SetLastTaskId(0);
indexSettings.IndexMappings = await _azureAIIndexDocumentManager.GetMappingsAsync(indexSettings.IndexedContentTypes);
indexSettings.IndexFullName = _indexManager.GetFullIndexName(indexSettings.IndexName);

if (await _indexManager.CreateAsync(indexSettings))
{
await _azureAISearchIndexSettingsService.UpdateAsync(indexSettings);

indexNames.Add(indexSettings.IndexName);
newIndexNames.Add(indexSettings.IndexName);
}
}
}
Expand All @@ -97,7 +112,7 @@ await HttpBackgroundJob.ExecuteAfterEndOfRequestAsync(AzureAISearchIndexRebuildD
{
var searchIndexingService = scope.ServiceProvider.GetService<AzureAISearchIndexingService>();

await searchIndexingService.ProcessContentItemsAsync(indexNames.ToArray());
await searchIndexingService.ProcessContentItemsAsync(newIndexNames.ToArray());
});
}
}

0 comments on commit 21d2a70

Please sign in to comment.