mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Adding Lucene analyzer extensibility point
This commit is contained in:
@@ -59,7 +59,9 @@ namespace Orchard.Tests.Modules.Indexing {
|
||||
Directory.CreateDirectory(_basePath);
|
||||
_contentDefinitionManager = new Mock<IContentDefinitionManager>();
|
||||
_appDataFolder = AppDataFolderTests.CreateAppDataFolder(_basePath);
|
||||
|
||||
|
||||
builder.RegisterType<DefaultLuceneAnalyzerProvider>().As<ILuceneAnalyzerProvider>();
|
||||
builder.RegisterType<DefaultLuceneAnalyzerSelector>().As<ILuceneAnalyzerSelector>();
|
||||
builder.RegisterType<LuceneIndexProvider>().As<IIndexProvider>();
|
||||
builder.RegisterInstance(_appDataFolder).As<IAppDataFolder>();
|
||||
builder.RegisterType<IndexingTaskExecutor>().As<IIndexingTaskExecutor>();
|
||||
|
@@ -35,6 +35,8 @@ namespace Orchard.Tests.Modules.Indexing {
|
||||
_appDataFolder = AppDataFolderTests.CreateAppDataFolder(_basePath);
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<DefaultLuceneAnalyzerProvider>().As<ILuceneAnalyzerProvider>();
|
||||
builder.RegisterType<DefaultLuceneAnalyzerSelector>().As<ILuceneAnalyzerSelector>();
|
||||
builder.RegisterType<LuceneIndexProvider>().As<IIndexProvider>();
|
||||
builder.RegisterInstance(_appDataFolder).As<IAppDataFolder>();
|
||||
|
||||
|
@@ -34,6 +34,8 @@ namespace Orchard.Tests.Modules.Indexing {
|
||||
_appDataFolder = AppDataFolderTests.CreateAppDataFolder(_basePath);
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<DefaultLuceneAnalyzerProvider>().As<ILuceneAnalyzerProvider>();
|
||||
builder.RegisterType<DefaultLuceneAnalyzerSelector>().As<ILuceneAnalyzerSelector>();
|
||||
builder.RegisterType<LuceneIndexProvider>().As<IIndexProvider>();
|
||||
builder.RegisterInstance(_appDataFolder).As<IAppDataFolder>();
|
||||
|
||||
|
@@ -71,6 +71,11 @@
|
||||
<Compile Include="Models\LuceneDocumentIndex.cs" />
|
||||
<Compile Include="Models\LuceneSearchHit.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Services\DefaultLuceneAnalyzerSelector.cs" />
|
||||
<Compile Include="Services\DefaultLuceneAnalyzerProvider.cs" />
|
||||
<Compile Include="Services\ILuceneAnalyzerProvider.cs" />
|
||||
<Compile Include="Services\ILuceneAnalyzerSelector.cs" />
|
||||
<Compile Include="Services\LuceneAnalyzerSelectorResult.cs" />
|
||||
<Compile Include="Services\LuceneIndexProvider.cs" />
|
||||
<Compile Include="Services\LuceneSearchBuilder.cs" />
|
||||
<Compile Include="Services\SearchBits.cs" />
|
||||
|
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Lucene.Net.Analysis;
|
||||
using Lucene.Net.Analysis.Standard;
|
||||
using Orchard;
|
||||
|
||||
namespace Lucene.Services {
|
||||
public class DefaultLuceneAnalyzerProvider : ILuceneAnalyzerProvider {
|
||||
|
||||
private IEnumerable<ILuceneAnalyzerSelector> _analyzerSelectors;
|
||||
|
||||
public DefaultLuceneAnalyzerProvider(IEnumerable<ILuceneAnalyzerSelector> analyzerSelectors) {
|
||||
_analyzerSelectors = analyzerSelectors;
|
||||
}
|
||||
|
||||
public Analyzer GetAnalyzer(string indexName) {
|
||||
var analyzer = _analyzerSelectors
|
||||
.Select(x => x.GetLuceneAnalyzer(indexName))
|
||||
.Where(x => x != null)
|
||||
.OrderByDescending(x => x.Priority)
|
||||
.Select(x => x.Analyzer)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (analyzer != null) {
|
||||
return analyzer;
|
||||
}
|
||||
|
||||
return new StandardAnalyzer(LuceneIndexProvider.LuceneVersion);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using Lucene.Net.Analysis.Standard;
|
||||
|
||||
namespace Lucene.Services {
|
||||
public class DefaultLuceneAnalyzerSelector : ILuceneAnalyzerSelector {
|
||||
public LuceneAnalyzerSelectorResult GetLuceneAnalyzer(string indexName) {
|
||||
return new LuceneAnalyzerSelectorResult {
|
||||
Priority = -5,
|
||||
Analyzer = new StandardAnalyzer(LuceneIndexProvider.LuceneVersion)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Lucene.Net.Analysis;
|
||||
using Orchard;
|
||||
|
||||
namespace Lucene.Services {
|
||||
public interface ILuceneAnalyzerProvider : IDependency {
|
||||
Analyzer GetAnalyzer(string indexName);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using Orchard;
|
||||
|
||||
namespace Lucene.Services {
|
||||
public interface ILuceneAnalyzerSelector : IDependency {
|
||||
LuceneAnalyzerSelectorResult GetLuceneAnalyzer(string indexName);
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using Lucene.Net.Analysis;
|
||||
|
||||
namespace Lucene.Services {
|
||||
public class LuceneAnalyzerSelectorResult {
|
||||
public int Priority { get; set; }
|
||||
public Analyzer Analyzer { get; set; }
|
||||
}
|
||||
}
|
@@ -24,14 +24,18 @@ namespace Lucene.Services {
|
||||
/// </summary>
|
||||
public class LuceneIndexProvider : IIndexProvider {
|
||||
private readonly IAppDataFolder _appDataFolder;
|
||||
public static readonly Version LuceneVersion = Version.LUCENE_29;
|
||||
private readonly Analyzer _analyzer ;
|
||||
private readonly string _basePath;
|
||||
public static readonly DateTime DefaultMinDateTime = new DateTime(1980, 1, 1);
|
||||
private ILuceneAnalyzerProvider _analyzerProvider;
|
||||
|
||||
public LuceneIndexProvider(IAppDataFolder appDataFolder, ShellSettings shellSettings) {
|
||||
public static readonly Version LuceneVersion = Version.LUCENE_29;
|
||||
public static readonly DateTime DefaultMinDateTime = new DateTime(1980, 1, 1);
|
||||
|
||||
public LuceneIndexProvider(
|
||||
IAppDataFolder appDataFolder,
|
||||
ShellSettings shellSettings,
|
||||
ILuceneAnalyzerProvider analyzerProvider) {
|
||||
_appDataFolder = appDataFolder;
|
||||
_analyzer = CreateAnalyzer();
|
||||
_analyzerProvider = analyzerProvider;
|
||||
|
||||
// TODO: (sebros) Find a common way to get where tenant's specific files should go. "Sites/Tenant" is hard coded in multiple places
|
||||
_basePath = _appDataFolder.Combine("Sites", shellSettings.Name, "Indexes");
|
||||
@@ -48,18 +52,13 @@ namespace Lucene.Services {
|
||||
public Localizer T { get; set; }
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public static Analyzer CreateAnalyzer() {
|
||||
// StandardAnalyzer does lower-case and stop-word filtering. It also removes punctuation
|
||||
return new StandardAnalyzer(LuceneVersion);
|
||||
}
|
||||
|
||||
private void EnsureDirectoryExists() {
|
||||
var directory = new DirectoryInfo(_appDataFolder.MapPath(_basePath));
|
||||
if(!directory.Exists) {
|
||||
directory.Create();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected virtual Directory GetDirectory(string indexName) {
|
||||
var directoryInfo = new DirectoryInfo(_appDataFolder.MapPath(_appDataFolder.Combine(_basePath, indexName)));
|
||||
return FSDirectory.Open(directoryInfo);
|
||||
@@ -104,7 +103,7 @@ namespace Lucene.Services {
|
||||
}
|
||||
|
||||
public void CreateIndex(string indexName) {
|
||||
using (new IndexWriter(GetDirectory(indexName), _analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED)) {
|
||||
using (new IndexWriter(GetDirectory(indexName), _analyzerProvider.GetAnalyzer(indexName), true, IndexWriter.MaxFieldLength.UNLIMITED)) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +130,7 @@ namespace Lucene.Services {
|
||||
// Remove any previous document for these content items
|
||||
Delete(indexName, indexDocuments.Select(i => i.ContentItemId));
|
||||
|
||||
using(var writer = new IndexWriter(GetDirectory(indexName), _analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED)) {
|
||||
using (var writer = new IndexWriter(GetDirectory(indexName), _analyzerProvider.GetAnalyzer(indexName), false, IndexWriter.MaxFieldLength.UNLIMITED)) {
|
||||
foreach (var indexDocument in indexDocuments) {
|
||||
var doc = CreateDocument(indexDocument);
|
||||
|
||||
@@ -151,8 +150,8 @@ namespace Lucene.Services {
|
||||
if (!documentIds.Any()) {
|
||||
return;
|
||||
}
|
||||
|
||||
using(var writer = new IndexWriter(GetDirectory(indexName), _analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED)) {
|
||||
|
||||
using (var writer = new IndexWriter(GetDirectory(indexName), _analyzerProvider.GetAnalyzer(indexName), false, IndexWriter.MaxFieldLength.UNLIMITED)) {
|
||||
var query = new BooleanQuery();
|
||||
|
||||
try {
|
||||
@@ -173,7 +172,7 @@ namespace Lucene.Services {
|
||||
}
|
||||
|
||||
public ISearchBuilder CreateSearchBuilder(string indexName) {
|
||||
return new LuceneSearchBuilder(GetDirectory(indexName)) { Logger = Logger };
|
||||
return new LuceneSearchBuilder(GetDirectory(indexName), _analyzerProvider, indexName) { Logger = Logger };
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetFields(string indexName) {
|
||||
|
@@ -19,6 +19,8 @@ namespace Lucene.Services {
|
||||
private const int MaxResults = Int16.MaxValue;
|
||||
|
||||
private readonly Directory _directory;
|
||||
private ILuceneAnalyzerProvider _analyzerProvider;
|
||||
private string _indexName;
|
||||
|
||||
private readonly List<BooleanClause> _clauses;
|
||||
private readonly List<BooleanClause> _filters;
|
||||
@@ -34,12 +36,17 @@ namespace Lucene.Services {
|
||||
private bool _exactMatch;
|
||||
private float _boost;
|
||||
private Query _query;
|
||||
private readonly Analyzer _analyzer = LuceneIndexProvider.CreateAnalyzer();
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public LuceneSearchBuilder(Directory directory) {
|
||||
public LuceneSearchBuilder(
|
||||
Directory directory,
|
||||
ILuceneAnalyzerProvider analyzerProvider,
|
||||
string indexName) {
|
||||
_directory = directory;
|
||||
_indexName = indexName;
|
||||
_analyzerProvider = analyzerProvider;
|
||||
|
||||
Logger = NullLogger.Instance;
|
||||
|
||||
_count = MaxResults;
|
||||
@@ -72,7 +79,7 @@ namespace Lucene.Services {
|
||||
|
||||
foreach (var defaultField in defaultFields) {
|
||||
CreatePendingClause();
|
||||
_query = new QueryParser(LuceneIndexProvider.LuceneVersion, defaultField, _analyzer).Parse(query);
|
||||
_query = new QueryParser(LuceneIndexProvider.LuceneVersion, defaultField, _analyzerProvider.GetAnalyzer(_indexName)).Parse(query);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
Reference in New Issue
Block a user