mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00

Changed Parse() to use lucene syntax Moved everything to Orchard.Indexing New filters for search --HG-- branch : dev
148 lines
5.9 KiB
C#
148 lines
5.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using JetBrains.Annotations;
|
|
using Orchard.ContentManagement;
|
|
using Orchard.Data;
|
|
using Orchard.Indexing.Models;
|
|
using Orchard.Logging;
|
|
using Orchard.Services;
|
|
using Orchard.Tasks.Indexing;
|
|
|
|
namespace Orchard.Indexing.Services {
|
|
/// <summary>
|
|
/// Contains the logic which is regularly executed to retrieve index information from multiple content handlers.
|
|
/// </summary>
|
|
[UsedImplicitly]
|
|
public class IndexingTaskExecutor : IIndexNotifierHandler {
|
|
private readonly IClock _clock;
|
|
private readonly IRepository<IndexingTaskRecord> _repository;
|
|
private IIndexProvider _indexProvider;
|
|
private readonly IIndexManager _indexManager;
|
|
private readonly IIndexingTaskManager _indexingTaskManager;
|
|
private readonly IContentManager _contentManager;
|
|
private readonly IIndexSynLock _indexSynLock;
|
|
private const string SearchIndexName = "Search";
|
|
|
|
public IndexingTaskExecutor(
|
|
IClock clock,
|
|
IRepository<IndexingTaskRecord> repository,
|
|
IIndexManager indexManager,
|
|
IIndexingTaskManager indexingTaskManager,
|
|
IContentManager contentManager,
|
|
IIndexSynLock indexSynLock) {
|
|
_clock = clock;
|
|
_repository = repository;
|
|
_indexManager = indexManager;
|
|
_indexingTaskManager = indexingTaskManager;
|
|
_contentManager = contentManager;
|
|
_indexSynLock = indexSynLock;
|
|
Logger = NullLogger.Instance;
|
|
}
|
|
|
|
public ILogger Logger { get; set; }
|
|
|
|
public void UpdateIndex(string indexName) {
|
|
var synLock = _indexSynLock.GetSynLock(SearchIndexName);
|
|
|
|
if ( !System.Threading.Monitor.TryEnter(synLock) ) {
|
|
Logger.Information("Index was requested but was already running");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
|
|
if (!_indexManager.HasIndexProvider()) {
|
|
return;
|
|
}
|
|
|
|
_indexProvider = _indexManager.GetSearchIndexProvider();
|
|
var updateIndexDocuments = new List<IDocumentIndex>();
|
|
DateTime lastIndexing;
|
|
|
|
// Do we need to rebuild the full index (first time module is used, or rebuild index requested) ?
|
|
if (_indexProvider.IsEmpty(SearchIndexName)) {
|
|
Logger.Information("Rebuild index started");
|
|
|
|
// mark current last task, as we should process older ones (in case of rebuild index only)
|
|
lastIndexing = _indexingTaskManager.GetLastTaskDateTime();
|
|
|
|
// get every existing content item to index it
|
|
foreach (var contentItem in _contentManager.Query(VersionOptions.Published).List()) {
|
|
try {
|
|
var documentIndex = _indexProvider.New(contentItem.Id);
|
|
|
|
_contentManager.Index(contentItem, documentIndex);
|
|
if(documentIndex.IsDirty) {
|
|
updateIndexDocuments.Add(documentIndex);
|
|
}
|
|
}
|
|
catch (Exception ex) {
|
|
Logger.Warning(ex, "Unable to index content item #{0} during rebuild", contentItem.Id);
|
|
}
|
|
}
|
|
|
|
}
|
|
else {
|
|
// retrieve last processed index time
|
|
lastIndexing = _indexProvider.GetLastIndexUtc(SearchIndexName);
|
|
}
|
|
|
|
_indexProvider.SetLastIndexUtc(SearchIndexName, _clock.UtcNow);
|
|
|
|
// retrieve not yet processed tasks
|
|
var taskRecords = _repository.Fetch(x => x.CreatedUtc > lastIndexing)
|
|
.ToArray();
|
|
|
|
// nothing to do ?
|
|
if (taskRecords.Length + updateIndexDocuments.Count == 0)
|
|
return;
|
|
|
|
Logger.Information("Processing {0} indexing tasks", taskRecords.Length);
|
|
|
|
if (!_indexProvider.Exists(SearchIndexName)) {
|
|
_indexProvider.CreateIndex(SearchIndexName);
|
|
}
|
|
|
|
// process Delete tasks
|
|
try {
|
|
_indexProvider.Delete(SearchIndexName, taskRecords.Where(t => t.Action == IndexingTaskRecord.Delete).Select(t => t.Id));
|
|
}
|
|
catch (Exception ex) {
|
|
Logger.Warning(ex, "An error occured while removing a document from the index");
|
|
}
|
|
|
|
// process Update tasks
|
|
foreach (var taskRecord in taskRecords.Where(t => t.Action == IndexingTaskRecord.Update)) {
|
|
var task = new IndexingTask(_contentManager, taskRecord);
|
|
|
|
try {
|
|
var documentIndex = _indexProvider.New(task.ContentItem.Id);
|
|
|
|
_contentManager.Index(task.ContentItem, documentIndex);
|
|
if ( documentIndex.IsDirty ) {
|
|
updateIndexDocuments.Add(documentIndex);
|
|
}
|
|
|
|
}
|
|
catch (Exception ex) {
|
|
Logger.Warning(ex, "Unable to process indexing task #{0}", taskRecord.Id);
|
|
}
|
|
}
|
|
|
|
if (updateIndexDocuments.Count > 0) {
|
|
try {
|
|
_indexProvider.Store(SearchIndexName, updateIndexDocuments);
|
|
}
|
|
catch (Exception ex) {
|
|
Logger.Warning(ex, "An error occured while adding a document to the index");
|
|
}
|
|
}
|
|
}
|
|
finally {
|
|
System.Threading.Monitor.Exit(synLock);
|
|
}
|
|
}
|
|
}
|
|
}
|