diff --git a/core/Piranha.Azure.Search/Content.cs b/core/Piranha.Azure.Search/Content.cs
index 19ced70ac..d61576cd9 100644
--- a/core/Piranha.Azure.Search/Content.cs
+++ b/core/Piranha.Azure.Search/Content.cs
@@ -10,9 +10,8 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
-using Microsoft.Azure.Search;
-using Microsoft.Azure.Search.Models;
-using Microsoft.Spatial;
+using Azure.Search.Documents.Indexes;
+using Azure.Search.Documents.Indexes.Models;
using Piranha.Models;
namespace Piranha.Azure.Search
@@ -20,7 +19,6 @@ namespace Piranha.Azure.Search
///
/// Search index model for Azure Search.
///
- [SerializePropertyNamesAsCamelCase]
public class Content
{
///
@@ -32,46 +30,37 @@ public class Content
///
/// Gets/sets the content slug.
///
- [IsSearchable]
- [Analyzer(AnalyzerName.AsString.StandardLucene)]
+ [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.StandardLucene)]
public string Slug { get; set; }
///
/// Gets/sets the content type.
///
- [IsFilterable]
+ [SimpleField(IsFilterable = true)]
public string ContentType { get; set; }
///
/// Gets/sets the main title.
///
- [IsSearchable]
- [IsSortable]
- [Analyzer(AnalyzerName.AsString.StandardLucene)]
+ [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.StandardLucene, IsSortable = true)]
public string Title { get; set; }
///
/// Gets/sets the optional category.
///
- [IsFilterable]
- [IsSearchable]
- [IsSortable]
- [Analyzer(AnalyzerName.AsString.StandardLucene)]
+ [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.StandardLucene, IsFilterable = true, IsSortable = true)]
public string Category { get; set; }
///
/// Gets/sets the optional tags.
///
- [IsFilterable]
- [IsSearchable]
- [Analyzer(AnalyzerName.AsString.StandardLucene)]
+ [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.StandardLucene, IsFilterable = true, IsFacetable = true)]
public IList Tags { get; set; } = new List();
///
/// Gets/sets the main body.
///
- [IsSearchable]
- [Analyzer(AnalyzerName.AsString.StandardLucene)]
+ [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.StandardLucene)]
public string Body { get; set; }
}
}
\ No newline at end of file
diff --git a/core/Piranha.Azure.Search/Piranha.Azure.Search.csproj b/core/Piranha.Azure.Search/Piranha.Azure.Search.csproj
index 712b81312..bb278dd08 100644
--- a/core/Piranha.Azure.Search/Piranha.Azure.Search.csproj
+++ b/core/Piranha.Azure.Search/Piranha.Azure.Search.csproj
@@ -6,8 +6,8 @@
+
-
diff --git a/core/Piranha.Azure.Search/PiranhaSearchExtensions.cs b/core/Piranha.Azure.Search/PiranhaSearchExtensions.cs
index 944f9d202..eca9b6cc4 100644
--- a/core/Piranha.Azure.Search/PiranhaSearchExtensions.cs
+++ b/core/Piranha.Azure.Search/PiranhaSearchExtensions.cs
@@ -19,13 +19,14 @@ public static class PiranhaSearchExtensions
/// Adds the Azure Search module.
///
/// The service builder
- /// The unique name of the azure search service
+ /// The url of the azure search service
/// The admin api key
+ /// The name of the search index
/// The services
public static PiranhaServiceBuilder UseAzureSearch(this PiranhaServiceBuilder serviceBuilder,
- string serviceName, string apiKey)
+ string serviceUrl, string apiKey, string index)
{
- serviceBuilder.Services.AddPiranhaAzureSearch(serviceName, apiKey);
+ serviceBuilder.Services.AddPiranhaAzureSearch(serviceUrl, apiKey, index);
return serviceBuilder;
}
@@ -34,17 +35,18 @@ public static PiranhaServiceBuilder UseAzureSearch(this PiranhaServiceBuilder se
/// Adds the Azure Search module.
///
/// The current service collection
- /// The unique name of the azure search service
+ /// The url of the azure search service
/// The admin api key
+ /// The name of the search index
/// The services
public static IServiceCollection AddPiranhaAzureSearch(this IServiceCollection services,
- string serviceName, string apiKey)
+ string serviceUrl, string apiKey, string index)
{
// Add the identity module
App.Modules.Register();
// Register the search service
- services.AddSingleton(new AzureSearchService(serviceName, apiKey));
+ services.AddSingleton(new AzureSearchService(serviceUrl, apiKey, index));
return services;
}
diff --git a/core/Piranha.Azure.Search/Services/AzureSearchService.cs b/core/Piranha.Azure.Search/Services/AzureSearchService.cs
index 03d2cb198..ec4b23bd5 100644
--- a/core/Piranha.Azure.Search/Services/AzureSearchService.cs
+++ b/core/Piranha.Azure.Search/Services/AzureSearchService.cs
@@ -8,13 +8,17 @@
*
*/
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
-using Microsoft.Azure.Search;
-using Microsoft.Azure.Search.Models;
+using Azure;
+using Azure.Search.Documents;
+using Azure.Search.Documents.Indexes;
+using Azure.Search.Documents.Indexes.Models;
+using Azure.Search.Documents.Models;
using Piranha.Extend;
using Piranha.Models;
@@ -25,37 +29,38 @@ namespace Piranha.Azure.Search.Services
///
public class AzureSearchService : ISearch
{
- private readonly string _serviceName = "";
+ private readonly string _serviceUrl = "";
private readonly string _apiKey = "";
+ private readonly string _index = "";
///
/// Default constructor.
///
- /// The search service name
+ /// The search service url
/// The admin api key
- public AzureSearchService(string serviceName, string apiKey)
+ /// Name of the search index
+ public AzureSearchService(string serviceUrl, string apiKey, string index)
{
- _serviceName = serviceName;
+ _serviceUrl = serviceUrl;
_apiKey = apiKey;
+ _index = index.ToLowerInvariant();
// Make sure the search indexes are up to date
- CreateIndexes();
+ CreateIndex(_index);
}
///
/// Creates the main search indexes.
///
- public void CreateIndexes()
+ private void CreateIndex(string indexName)
{
- using (var client = CreateClient())
- {
- var contentIndex = new Index()
- {
- Name = "content",
- Fields = FieldBuilder.BuildForType()
- };
- client.Indexes.CreateOrUpdate(contentIndex);
- }
+ var indexClient = CreateSearchIndexClient();
+ FieldBuilder fieldBuilder = new FieldBuilder();
+ var searchFields = fieldBuilder.Build(typeof(Content));
+
+ var definition = new SearchIndex(indexName, searchFields);
+
+ indexClient.CreateOrUpdateIndex(definition);
}
///
@@ -65,41 +70,36 @@ public void CreateIndexes()
/// The page
public async Task SavePageAsync(PageBase page)
{
- using (var client = CreateClient())
- {
- var indexClient = client.Indexes.GetClient("content");
- var body = new StringBuilder();
-
- foreach (var block in page.Blocks)
- {
- if (block is ISearchable searchableBlock)
- {
- body.AppendLine(searchableBlock.GetIndexedContent());
- }
- }
-
- var cleanHtml = new Regex("<[^>]*(>|$)");
- var cleanSpaces = new Regex("[\\s\\r\\n]+");
+ var client = CreateSearchClient();
- var cleaned = cleanSpaces.Replace(cleanHtml.Replace(body.ToString(), " "), " ").Trim();
+ var body = new StringBuilder();
- var actions = new IndexAction[]
+ foreach (var block in page.Blocks)
+ {
+ if (block is ISearchable searchableBlock)
{
- IndexAction.MergeOrUpload(
- new Content
- {
- Slug = page.Slug,
- ContentId = page.Id.ToString(),
- ContentType = "page",
- Title = page.Title,
- Body = cleaned
- }
- )
- };
- var batch = IndexBatch.New(actions);
-
- await indexClient.Documents.IndexAsync(batch);
+ body.AppendLine(searchableBlock.GetIndexedContent());
+ }
}
+
+ var cleanHtml = new Regex("<[^>]*(>|$)");
+ var cleanSpaces = new Regex("[\\s\\r\\n]+");
+
+ var cleaned = cleanSpaces.Replace(cleanHtml.Replace(body.ToString(), " "), " ").Trim();
+
+ IndexDocumentsBatch batch = IndexDocumentsBatch.Create(
+ IndexDocumentsAction.MergeOrUpload(
+ new Content
+ {
+ Slug = page.Slug,
+ ContentId = page.Id.ToString(),
+ ContentType = "page",
+ Title = page.Title,
+ Body = cleaned
+ }
+ )
+ );
+ await client.IndexDocumentsAsync(batch);
}
///
@@ -108,14 +108,9 @@ public async Task SavePageAsync(PageBase page)
/// The page to delete
public async Task DeletePageAsync(PageBase page)
{
- using (var client = CreateClient())
- {
- var indexClient = client.Indexes.GetClient("content");
-
- var batch = IndexBatch.Delete("contentId", new List { page.Id.ToString() });
-
- await indexClient.Documents.IndexAsync(batch);
- }
+ var client = CreateSearchClient();
+ var batch = IndexDocumentsBatch.Delete("contentId", new List { page.Id.ToString() });
+ await client.IndexDocumentsAsync(batch);
}
///
@@ -125,43 +120,37 @@ public async Task DeletePageAsync(PageBase page)
/// The post
public async Task SavePostAsync(PostBase post)
{
- using (var client = CreateClient())
- {
- var indexClient = client.Indexes.GetClient("content");
- var body = new StringBuilder();
+ var client = CreateSearchClient();
+ var body = new StringBuilder();
- foreach (var block in post.Blocks)
+ foreach (var block in post.Blocks)
+ {
+ if (block is ISearchable searchableBlock)
{
- if (block is ISearchable searchableBlock)
- {
- body.AppendLine(searchableBlock.GetIndexedContent());
- }
+ body.AppendLine(searchableBlock.GetIndexedContent());
}
-
- var cleanHtml = new Regex("<[^>]*(>|$)");
- var cleanSpaces = new Regex("[\\s\\r\\n]+");
-
- var cleaned = cleanSpaces.Replace(cleanHtml.Replace(body.ToString(), " "), " ").Trim();
-
- var actions = new IndexAction[]
- {
- IndexAction.MergeOrUpload(
- new Content
- {
- Slug = post.Slug,
- ContentId = post.Id.ToString(),
- ContentType = "post",
- Title = post.Title,
- Category = post.Category.Title,
- Tags = post.Tags.Select(t => t.Title).ToList(),
- Body = cleaned
- }
- )
- };
- var batch = IndexBatch.New(actions);
-
- await indexClient.Documents.IndexAsync(batch);
}
+
+ var cleanHtml = new Regex("<[^>]*(>|$)");
+ var cleanSpaces = new Regex("[\\s\\r\\n]+");
+
+ var cleaned = cleanSpaces.Replace(cleanHtml.Replace(body.ToString(), " "), " ").Trim();
+
+ IndexDocumentsBatch batch = IndexDocumentsBatch.Create(
+ IndexDocumentsAction.MergeOrUpload(
+ new Content
+ {
+ Slug = post.Slug,
+ ContentId = post.Id.ToString(),
+ ContentType = "post",
+ Title = post.Title,
+ Category = post.Category.Title,
+ Tags = post.Tags.Select(t => t.Title).ToList(),
+ Body = cleaned
+ }
+ )
+ );
+ await client.IndexDocumentsAsync(batch);
}
///
@@ -170,22 +159,27 @@ public async Task SavePostAsync(PostBase post)
/// The post to delete
public async Task DeletePostAsync(PostBase post)
{
- using (var client = CreateClient())
- {
- var indexClient = client.Indexes.GetClient("content");
-
- var batch = IndexBatch.Delete("contentId", new List { post.Id.ToString() });
+ var client = CreateSearchClient();
+ var batch = IndexDocumentsBatch.Delete("contentId", new List { post.Id.ToString() });
+ await client.IndexDocumentsAsync(batch);
+ }
- await indexClient.Documents.IndexAsync(batch);
- }
+ ///
+ /// Creates the SearchIndexClient.
+ ///
+ private SearchIndexClient CreateSearchIndexClient()
+ {
+ SearchIndexClient indexClient = new SearchIndexClient(new Uri(_serviceUrl), new AzureKeyCredential(_apiKey));
+ return indexClient;
}
///
- /// Creates the search client.
+ /// Creates the SearchClient.
///
- private SearchServiceClient CreateClient()
+ private SearchClient CreateSearchClient()
{
- return new SearchServiceClient(_serviceName, new SearchCredentials(_apiKey));
+ SearchClient searchClient = new SearchClient(new Uri(_serviceUrl), _index, new AzureKeyCredential(_apiKey));
+ return searchClient;
}
}
}
\ No newline at end of file