private async Task WriteAsync(string indexName, Action <IndexWriter> action, bool close = false) { if (!_writers.TryGetValue(indexName, out var writer)) { var indexAnalyzer = await _luceneIndexSettingsService.GetIndexAnalyzerAsync(indexName); lock (this) { if (!_writers.TryGetValue(indexName, out writer)) { var directory = CreateDirectory(indexName); var analyzer = _luceneAnalyzerManager.CreateAnalyzer(indexAnalyzer); var config = new IndexWriterConfig(LuceneSettings.DefaultVersion, analyzer) { OpenMode = OpenMode.CREATE_OR_APPEND, WriteLockTimeout = Lock.LOCK_POLL_INTERVAL * 3 }; writer = new IndexWriterWrapper(directory, config); if (close) { action?.Invoke(writer); writer.Dispose(); _timestamps[indexName] = _clock.UtcNow; return; } _writers[indexName] = writer; } } } if (writer.IsClosing) { return; } action?.Invoke(writer); _timestamps[indexName] = _clock.UtcNow; }
public async Task <IQueryResults> ExecuteQueryAsync(Query query, IDictionary <string, object> parameters) { var luceneQuery = query as LuceneQuery; var luceneQueryResults = new LuceneQueryResults(); await _luceneIndexProvider.SearchAsync(luceneQuery.Index, async searcher => { var templateContext = new TemplateContext(); if (parameters != null) { foreach (var parameter in parameters) { templateContext.SetValue(parameter.Key, parameter.Value); } } var tokenizedContent = await _liquidTemplateManager.RenderAsync(luceneQuery.Template, System.Text.Encodings.Web.JavaScriptEncoder.Default, templateContext); var parameterizedQuery = JObject.Parse(tokenizedContent); var analyzer = _luceneAnalyzerManager.CreateAnalyzer(await _luceneIndexSettingsService.GetIndexAnalyzerAsync(luceneQuery.Index)); var context = new LuceneQueryContext(searcher, LuceneSettings.DefaultVersion, analyzer); var docs = await _queryService.SearchAsync(context, parameterizedQuery); luceneQueryResults.Count = docs.Count; if (luceneQuery.ReturnContentItems) { // We always return an empty collection if the bottom lines queries have no results. luceneQueryResults.Items = new List <ContentItem>(); // Load corresponding content item versions var indexedContentItemVersionIds = docs.TopDocs.ScoreDocs.Select(x => searcher.Doc(x.Doc).Get("Content.ContentItem.ContentItemVersionId")).ToArray(); var dbContentItems = await _session.Query <ContentItem, ContentItemIndex>(x => x.ContentItemVersionId.IsIn(indexedContentItemVersionIds)).ListAsync(); // Reorder the result to preserve the one from the lucene query if (dbContentItems.Any()) { var dbContentItemVersionIds = dbContentItems.ToDictionary(x => x.ContentItemVersionId, x => x); var indexedAndInDB = indexedContentItemVersionIds.Where(dbContentItemVersionIds.ContainsKey); luceneQueryResults.Items = indexedAndInDB.Select(x => dbContentItemVersionIds[x]).ToArray(); } } else { var results = new List <JObject>(); foreach (var document in docs.TopDocs.ScoreDocs.Select(hit => searcher.Doc(hit.Doc))) { results.Add(new JObject(document.Select(x => new JProperty(x.Name, x.GetStringValue())))); } luceneQueryResults.Items = results; } }); return(luceneQueryResults); }