Browse Source

Code improvement.

pull/351/head
Sebastian Stehle 7 years ago
parent
commit
02976bf663
  1. 172
      src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexContent.cs
  2. 73
      src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexerGrain.cs

172
src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexContent.cs

@ -0,0 +1,172 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Text;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Search;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Entities.Contents.Text
{
internal sealed class TextIndexContent
{
public const string MetaId = "_id";
public const string MetaKey = "_key";
public const string MetaDraft = "_dd";
private readonly IndexWriter indexWriter;
private readonly IndexSearcher indexSearcher;
private readonly Guid id;
public TextIndexContent(IndexWriter indexWriter, IndexSearcher indexSearcher, Guid id)
{
this.indexWriter = indexWriter;
this.indexSearcher = indexSearcher;
this.id = id;
}
public void Index(NamedContentData data, bool isDraft)
{
var converted = CreateDocument(data);
Upsert(converted, isDraft);
}
public void Delete()
{
indexWriter.DeleteDocuments(new Term(MetaId, id.ToString()));
}
public void Copy(bool fromDraft)
{
var published = GetDocument(fromDraft);
Upsert(published, !fromDraft);
}
private Document CreateDocument(NamedContentData data)
{
var languages = new Dictionary<string, StringBuilder>();
void AppendText(string language, string text)
{
if (!string.IsNullOrWhiteSpace(text))
{
var sb = languages.GetOrAddNew(language);
if (sb.Length > 0)
{
sb.Append(" ");
}
sb.Append(text);
}
}
foreach (var field in data)
{
foreach (var fieldValue in field.Value)
{
var appendText = new Action<string>(text => AppendText(fieldValue.Key, text));
AppendJsonText(fieldValue.Value, appendText);
}
}
Document document = null;
if (languages.Count > 0)
{
document = new Document();
foreach (var field in languages)
{
document.AddTextField(field.Key, field.Value.ToString(), Field.Store.NO);
}
}
return document;
}
private Document GetDocument(bool draft)
{
if (indexSearcher == null)
{
return null;
}
var docs = indexSearcher.Search(new TermQuery(new Term(MetaKey, BuildKey(BuildValue(draft)))), 1);
if (docs.ScoreDocs.Length > 0)
{
return indexSearcher.Doc(docs.ScoreDocs[0].Doc);
}
return null;
}
private void Upsert(Document document, bool draft)
{
if (document != null)
{
document.RemoveField(MetaId);
document.RemoveField(MetaKey);
document.RemoveField(MetaDraft);
var docDraft = BuildValue(draft);
var docId = id.ToString();
var docKey = BuildKey(docDraft);
document.AddStringField(MetaId, docId, Field.Store.YES);
document.AddStringField(MetaKey, docKey, Field.Store.YES);
document.AddStringField(MetaDraft, docDraft, Field.Store.YES);
indexWriter.DeleteDocuments(new Term(MetaKey, docKey));
indexWriter.AddDocument(document);
}
}
private static string BuildValue(bool draft)
{
return draft ? "1" : "0";
}
private string BuildKey(string draft)
{
return $"{id}_{draft}";
}
private static void AppendJsonText(IJsonValue value, Action<string> appendText)
{
if (value.Type == JsonValueType.String)
{
appendText(value.ToString());
}
else if (value is JsonArray array)
{
foreach (var item in array)
{
AppendJsonText(item, appendText);
}
}
else if (value is JsonObject obj)
{
foreach (var item in obj.Values)
{
AppendJsonText(item, appendText);
}
}
}
}
}

73
src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexerGrain.cs

@ -32,13 +32,10 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text
private const LuceneVersion Version = LuceneVersion.LUCENE_48;
private const int MaxResults = 2000;
private const int MaxUpdates = 100;
private const string MetaId = "_id";
private const string MetaKey = "_key";
private const string MetaDraft = "_dd";
private static readonly TimeSpan CommitDelay = TimeSpan.FromSeconds(30);
private static readonly Analyzer Analyzer = new MultiLanguageAnalyzer(Version);
private static readonly TermsFilter DraftFilter = new TermsFilter(new Term(MetaDraft, "1"));
private static readonly TermsFilter NoDraftFilter = new TermsFilter(new Term(MetaDraft, "0"));
private static readonly TermsFilter DraftFilter = new TermsFilter(new Term(TextIndexContent.MetaDraft, "1"));
private static readonly TermsFilter NoDraftFilter = new TermsFilter(new Term(TextIndexContent.MetaDraft, "0"));
private readonly SnapshotDeletionPolicy snapshotter = new SnapshotDeletionPolicy(new KeepOnlyLastCommitDeletionPolicy());
private readonly IAssetStore assetStore;
private IDisposable timer;
@ -84,63 +81,18 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text
public Task DeleteAsync(Guid id)
{
indexWriter.DeleteDocuments(new Term(MetaId, id.ToString()));
var content = new TextIndexContent(indexWriter, indexSearcher, id);
content.Delete();
return TryFlushAsync();
}
public Task IndexAsync(Guid id, J<IndexData> data)
{
var docId = id.ToString();
var docDraft = data.Value.IsDraft ? "1" : "0";
var docKey = $"{docId}_{docDraft}";
indexWriter.DeleteDocuments(new Term(MetaKey, docKey));
var languages = new Dictionary<string, StringBuilder>();
void AppendText(string language, string text)
{
if (!string.IsNullOrWhiteSpace(text))
{
var sb = languages.GetOrAddNew(language);
var content = new TextIndexContent(indexWriter, indexSearcher, id);
if (sb.Length > 0)
{
sb.Append(" ");
}
sb.Append(text);
}
}
foreach (var field in data.Value.Data)
{
foreach (var fieldValue in field.Value)
{
var appendText = new Action<string>(text => AppendText(fieldValue.Key, text));
AppendJsonText(fieldValue.Value, appendText);
}
}
if (languages.Count > 0)
{
var document = new Document();
document.AddStringField(MetaId, docId, Field.Store.YES);
document.AddStringField(MetaKey, docKey, Field.Store.YES);
document.AddStringField(MetaDraft, docDraft, Field.Store.YES);
foreach (var field in languages)
{
var fieldName = BuildFieldName(field.Key);
document.AddTextField(fieldName, field.Value.ToString(), Field.Store.NO);
}
indexWriter.AddDocument(document);
}
content.Index(data.Value.Data, data.Value.IsDraft);
return TryFlushAsync();
}
@ -185,7 +137,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text
{
var document = indexReader.Document(hit.Doc);
var idField = document.GetField(MetaId)?.GetStringValue();
var idField = document.GetField(TextIndexContent.MetaId)?.GetStringValue();
if (idField != null && Guid.TryParse(idField, out var guid))
{
@ -203,8 +155,8 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text
if (queryParser == null || !currentLanguages.SetEquals(context.Languages))
{
var fields =
context.Languages.Select(BuildFieldName)
.Union(Enumerable.Repeat(BuildFieldName(InvariantPartitioning.Instance.Master.Key), 1)).ToArray();
context.Languages
.Union(Enumerable.Repeat(InvariantPartitioning.Instance.Master.Key, 1)).ToArray();
queryParser = new MultiFieldQueryParser(Version, fields, Analyzer);
@ -288,10 +240,5 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text
directory.Delete(true);
}
}
private static string BuildFieldName(string language)
{
return language;
}
}
}

Loading…
Cancel
Save