Adding faceted search capabilities

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros
2013-02-10 07:37:34 -08:00
parent 5c6b97d636
commit 836c00fb37
7 changed files with 100 additions and 0 deletions

View File

@@ -639,5 +639,24 @@ namespace Orchard.Tests.Modules.Indexing {
.WithField("field3", 3).Mandatory().AsFilter()
.Count(), Is.EqualTo(1));
}
[Test]
public void ShouldReturnFacetedResults() {
_provider.CreateIndex("default");
_provider.Store("default", _provider.New(1).Add("body", "michael is in the kitchen").Analyze());
_provider.Store("default", _provider.New(2).Add("body", "michael has a cousin named michel").Analyze());
_provider.Store("default", _provider.New(3).Add("body", "speak inside the mic").Analyze());
_provider.Store("default", _provider.New(4).Add("body", "a dog is pursuing a cat").Analyze());
_provider.Store("default", _provider.New(5).Add("body", "michael speaks to elephants").Analyze());
var michael = SearchBuilder.WithField("body", "michael").GetBits();
var speak = SearchBuilder.WithField("body", "speak").GetBits();
Assert.That(michael.Count(), Is.EqualTo(3));
Assert.That(speak.Count(), Is.EqualTo(2));
Assert.That(speak.And(michael).Count(), Is.EqualTo(1));
Assert.That(speak.Or(michael).Count(), Is.EqualTo(4));
Assert.That(speak.Xor(michael).Count(), Is.EqualTo(3));
}
}
}

View File

@@ -21,6 +21,10 @@
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>4.0</OldToolsVersion>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -66,6 +70,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\LuceneIndexProvider.cs" />
<Compile Include="Services\LuceneSearchBuilder.cs" />
<Compile Include="Services\SearchBits.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Module.txt" />

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@@ -6,6 +7,7 @@ using Lucene.Models;
using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Lucene.Net.Util;
using Orchard.Indexing;
using Orchard.Logging;
using Lucene.Net.Documents;
@@ -355,6 +357,30 @@ namespace Lucene.Services {
}
public ISearchBits GetBits() {
var query = CreateQuery();
IndexSearcher searcher;
try {
searcher = new IndexSearcher(_directory, true);
}
catch {
// index might not exist if it has been rebuilt
Logger.Information("Attempt to read a none existing index");
return null;
}
try {
var filter = new QueryWrapperFilter(query);
var bits = filter.GetDocIdSet(searcher.GetIndexReader());
var disi = new OpenBitSetDISI(bits.Iterator(), searcher.MaxDoc());
return new SearchBits(disi);
}
finally {
searcher.Close();
}
}
public ISearchHit Get(int documentId) {
var query = new TermQuery(new Term("id", documentId.ToString(CultureInfo.InvariantCulture)));

View File

@@ -0,0 +1,43 @@
using System;
using Lucene.Net.Util;
using Orchard.Indexing;
namespace Lucene.Services {
public class SearchBits : ISearchBits {
internal readonly OpenBitSet _openBitSet;
public SearchBits(OpenBitSet openBitSet) {
_openBitSet = openBitSet;
}
public ISearchBits And(ISearchBits other) {
return Apply(other, (x, y) => x.And(y));
}
public ISearchBits Or(ISearchBits other) {
return Apply(other, (x, y) => x.Or(y));
}
public ISearchBits Xor(ISearchBits other) {
return Apply(other, (x, y) => x.Xor(y));
}
public long Count() {
return _openBitSet.Cardinality();
}
private ISearchBits Apply(ISearchBits other, Action<OpenBitSet, OpenBitSet> operation) {
var bitset = (OpenBitSet)_openBitSet.Clone();
var otherBitSet = other as SearchBits;
if (otherBitSet == null) {
throw new InvalidOperationException("The other bitset must be of type OpenBitSet");
}
operation(bitset, otherBitSet._openBitSet);
return new SearchBits(bitset);
}
}
}

View File

@@ -57,6 +57,7 @@ namespace Orchard.Indexing {
ISearchBuilder Slice(int skip, int count);
IEnumerable<ISearchHit> Search();
ISearchHit Get(int documentId);
ISearchBits GetBits();
int Count();
}

View File

@@ -127,6 +127,11 @@ namespace Orchard.Indexing {
public ISearchHit Get(int documentId) {
return null;
}
public ISearchBits GetBits() {
throw new NotImplementedException();
}
public int Count() {
return 0;
}

View File

@@ -238,6 +238,7 @@
<Compile Include="FileSystems\LockFile\LockFile.cs" />
<Compile Include="FileSystems\LockFile\DefaultLockFileManager.cs" />
<Compile Include="FileSystems\Media\FileSystemStorageProvider.cs" />
<Compile Include="Indexing\ISearchBits.cs" />
<Compile Include="Localization\Services\CurrentCultureWorkContext.cs" />
<Compile Include="Localization\Services\DefaultLocalizedStringManager.cs" />
<Compile Include="Localization\Services\ILocalizedStringManager.cs" />