diff --git a/src/Umbraco.Core/Constants-Examine.cs b/src/Umbraco.Core/Constants-Examine.cs
index 4ff6115749..874965be6e 100644
--- a/src/Umbraco.Core/Constants-Examine.cs
+++ b/src/Umbraco.Core/Constants-Examine.cs
@@ -11,14 +11,14 @@ namespace Umbraco.Core
public static class Examine
{
///
- /// The alias of the internal member searcher
+ /// The alias of the internal member indexer
///
- public const string InternalMemberSearcher = "InternalMemberSearcher";
+ public const string InternalMemberIndexer = "InternalMemberIndexer";
///
- /// The alias of the internal content searcher
+ /// The alias of the internal content indexer
///
- public const string InternalSearcher = "InternalSearcher";
+ public const string InternalIndexer = "InternalIndexer";
}
}
}
diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs
index 6d031baee4..3383d97eb1 100644
--- a/src/Umbraco.Core/StringExtensions.cs
+++ b/src/Umbraco.Core/StringExtensions.cs
@@ -631,6 +631,11 @@ namespace Umbraco.Core
return str.ToString(CultureInfo.InvariantCulture);
}
+ public static string ToInvariantString(this long str)
+ {
+ return str.ToString(CultureInfo.InvariantCulture);
+ }
+
///
/// Compares 2 strings with invariant culture and case ignored
///
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index ee8aa696f2..2b940c8e78 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -56,7 +56,7 @@
True
- ..\packages\Examine.2.0.0-beta021\lib\net45\Examine.dll
+ ..\packages\Examine.2.0.0-beta023\lib\net45\Examine.dll
True
diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs
index b6b321f316..cd0344a377 100644
--- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs
+++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs
@@ -31,7 +31,6 @@ namespace Umbraco.Tests.UmbracoExamine
Analyzer analyzer = null,
IContentService contentService = null,
IMediaService mediaService = null,
- IDataTypeService dataTypeService = null,
IMemberService memberService = null,
IUserService userService = null,
UmbracoContentIndexerOptions options = null)
@@ -107,11 +106,7 @@ namespace Umbraco.Tests.UmbracoExamine
==
allRecs);
}
- if (dataTypeService == null)
- {
- dataTypeService = Mock.Of();
- }
-
+
if (analyzer == null)
{
analyzer = new StandardAnalyzer(Version.LUCENE_30);
@@ -148,7 +143,6 @@ namespace Umbraco.Tests.UmbracoExamine
profilingLogger,
contentService,
mediaService,
- dataTypeService,
userService,
new[] { new DefaultUrlSegmentProvider() },
new UmbracoContentValueSetValidator(options, Mock.Of()),
diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs b/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs
index 5167340491..163a2e42b7 100644
--- a/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs
+++ b/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs
@@ -34,7 +34,7 @@ namespace Umbraco.Tests.UmbracoExamine
{
using (var luceneDir = new RAMDirectory())
- using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, luceneDir))
+ using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, luceneDir, options: new UmbracoContentIndexerOptions(true, false, null)))
using (var session = new ThreadScopedIndexSession(indexer.SearcherContext))
{
var searcher = indexer.GetSearcher();
@@ -187,7 +187,7 @@ namespace Umbraco.Tests.UmbracoExamine
public void Index_Reindex_Content()
{
using (var luceneDir = new RAMDirectory())
- using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, luceneDir))
+ using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, luceneDir, options: new UmbracoContentIndexerOptions(true, false, null)))
using (var session = new ThreadScopedIndexSession(indexer.SearcherContext))
{
var searcher = indexer.GetSearcher();
diff --git a/src/Umbraco.Tests/UmbracoExamine/SearchTests.cs b/src/Umbraco.Tests/UmbracoExamine/SearchTests.cs
index 12047f2c5a..b85e8cc2ea 100644
--- a/src/Umbraco.Tests/UmbracoExamine/SearchTests.cs
+++ b/src/Umbraco.Tests/UmbracoExamine/SearchTests.cs
@@ -41,6 +41,7 @@ namespace Umbraco.Tests.UmbracoExamine
m.Name == (string)x.Attribute("nodeName") &&
m.Path == (string)x.Attribute("path") &&
m.Properties == new PropertyCollection() &&
+ m.Published == true &&
m.ContentType == Mock.Of(mt =>
mt.Icon == "test" &&
mt.Alias == x.Name.LocalName &&
diff --git a/src/Umbraco.Tests/packages.config b/src/Umbraco.Tests/packages.config
index 63c131688c..8c17514d92 100644
--- a/src/Umbraco.Tests/packages.config
+++ b/src/Umbraco.Tests/packages.config
@@ -2,7 +2,7 @@
-
+
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index 824214e0e6..2c07423989 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -121,7 +121,7 @@
True
- ..\packages\Examine.2.0.0-beta021\lib\net45\Examine.dll
+ ..\packages\Examine.2.0.0-beta023\lib\net45\Examine.dll
True
@@ -903,7 +903,7 @@
Form
-
+
diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config
index 78b0c1d4f1..bf3eca45e6 100644
--- a/src/Umbraco.Web.UI/packages.config
+++ b/src/Umbraco.Web.UI/packages.config
@@ -3,7 +3,7 @@
-
+
diff --git a/src/Umbraco.Web/Editors/EntityController.cs b/src/Umbraco.Web/Editors/EntityController.cs
index 596e27e3a5..ca1f9ec251 100644
--- a/src/Umbraco.Web/Editors/EntityController.cs
+++ b/src/Umbraco.Web/Editors/EntityController.cs
@@ -246,14 +246,14 @@ namespace Umbraco.Web.Editors
var sb = new StringBuilder();
string type;
- var searcher = Constants.Examine.InternalSearcher;
+
var fields = new[] { "id", "__NodeId" };
//TODO: WE should really just allow passing in a lucene raw query
switch (entityType)
{
case UmbracoEntityTypes.Member:
- searcher = Constants.Examine.InternalMemberSearcher;
+
type = "member";
fields = new[] { "id", "__NodeId", "email", "loginName"};
if (searchFrom != null && searchFrom != Constants.Conventions.MemberTypes.AllMembersListId && searchFrom.Trim() != "-1")
@@ -299,7 +299,7 @@ namespace Umbraco.Web.Editors
throw new NotSupportedException("The " + typeof(EntityController) + " currently does not support searching against object type " + entityType);
}
- var internalSearcher = ExamineManager.Instance.SearchProviderCollection[searcher];
+ var internalSearcher = ExamineManager.Instance.GetSearcher(Constants.Examine.InternalIndexer);
//build a lucene query:
// the __nodeName will be boosted 10x without wildcards
@@ -314,7 +314,7 @@ namespace Umbraco.Web.Editors
if (surroundedByQuotes)
{
//strip quotes, escape string, the replace again
- query = query.Trim(new[] { '\"', '\'' });
+ query = query.Trim('\"', '\'');
query = Lucene.Net.QueryParsers.QueryParser.Escape(query);
@@ -342,7 +342,7 @@ namespace Umbraco.Web.Editors
}
else
{
- if (query.Trim(new[] { '\"', '\'' }).IsNullOrWhiteSpace())
+ if (query.Trim('\"', '\'').IsNullOrWhiteSpace())
{
return new List();
}
@@ -390,10 +390,10 @@ namespace Umbraco.Web.Editors
sb.Append(type);
- var raw = internalSearcher.CreateSearchCriteria().RawQuery(sb.ToString());
+ var raw = internalSearcher.CreateCriteria().RawQuery(sb.ToString()).MaxCount(200);
//limit results to 200 to avoid huge over processing (CPU)
- var result = internalSearcher.Search(raw, 200);
+ var result = internalSearcher.Find(raw);
switch (entityType)
{
@@ -413,7 +413,7 @@ namespace Umbraco.Web.Editors
///
///
///
- private IEnumerable MemberFromSearchResults(ISearchResults results)
+ private IEnumerable MemberFromSearchResults(ILuceneSearchResults results)
{
var mapped = Mapper.Map>(results).ToArray();
//add additional data
@@ -425,10 +425,10 @@ namespace Umbraco.Web.Editors
m.Icon = "icon-user";
}
- var searchResult = results.First(x => x.Id.ToInvariantString() == m.Id.ToString());
+ var searchResult = results.First(x => x.LongId.ToInvariantString() == m.Id.ToString());
if (searchResult.Fields.ContainsKey("email") && searchResult.Fields["email"] != null)
{
- m.AdditionalData["Email"] = results.First(x => x.Id.ToInvariantString() == m.Id.ToString()).Fields["email"];
+ m.AdditionalData["Email"] = results.First(x => x.LongId.ToInvariantString() == m.Id.ToString()).Fields["email"];
}
if (searchResult.Fields.ContainsKey("__key") && searchResult.Fields["__key"] != null)
{
@@ -447,7 +447,7 @@ namespace Umbraco.Web.Editors
///
///
///
- private IEnumerable MediaFromSearchResults(ISearchResults results)
+ private IEnumerable MediaFromSearchResults(ILuceneSearchResults results)
{
var mapped = Mapper.Map>(results).ToArray();
//add additional data
@@ -467,9 +467,9 @@ namespace Umbraco.Web.Editors
///
///
///
- private IEnumerable ContentFromSearchResults(ISearchResults results)
+ private IEnumerable ContentFromSearchResults(ILuceneSearchResults results)
{
- var mapped = Mapper.Map>(results).ToArray();
+ var mapped = Mapper.Map>(results).ToArray();
//add additional data
foreach (var m in mapped)
{
diff --git a/src/Umbraco.Web/Models/Mapping/EntityModelMapper.cs b/src/Umbraco.Web/Models/Mapping/EntityModelMapper.cs
index f6e13fada4..659cb1bf50 100644
--- a/src/Umbraco.Web/Models/Mapping/EntityModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/EntityModelMapper.cs
@@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using Examine;
+using Examine.LuceneEngine;
+using Examine.LuceneEngine.Providers;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Mapping;
@@ -89,8 +91,8 @@ namespace Umbraco.Web.Models.Mapping
.AfterMap((result, basic) =>
{
//get the icon if there is one
- basic.Icon = result.Fields.ContainsKey(UmbracoContentIndexer.IconFieldName)
- ? result.Fields[UmbracoContentIndexer.IconFieldName]
+ basic.Icon = result.Fields.ContainsKey(BaseUmbracoIndexer.IconFieldName)
+ ? result.Fields[BaseUmbracoIndexer.IconFieldName]
: "icon-document";
basic.Name = result.Fields.ContainsKey("nodeName") ? result.Fields["nodeName"] : "[no name]";
@@ -116,13 +118,13 @@ namespace Umbraco.Web.Models.Mapping
}
basic.Path = result.Fields.ContainsKey("__Path") ? result.Fields["__Path"] : "";
- if (result.Fields.ContainsKey(UmbracoContentIndexer.NodeTypeAliasFieldName))
+ if (result.Fields.ContainsKey(LuceneIndexer.NodeTypeAliasFieldName))
{
- basic.AdditionalData.Add("contentType", result.Fields[UmbracoContentIndexer.NodeTypeAliasFieldName]);
+ basic.AdditionalData.Add("contentType", result.Fields[LuceneIndexer.NodeTypeAliasFieldName]);
}
});
- config.CreateMap>()
+ config.CreateMap>()
.ConvertUsing(results => results.Select(Mapper.Map).ToList());
}
}
diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs
index d4adafad23..25a8239186 100644
--- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs
+++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs
@@ -6,6 +6,7 @@ using System.IO;
using System.Linq;
using System.Xml.XPath;
using Examine;
+using Examine.LuceneEngine;
using Examine.LuceneEngine.Providers;
using Examine.LuceneEngine.SearchCriteria;
using Examine.Providers;
@@ -158,7 +159,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
try
{
//by default use the InternalSearcher
- return eMgr.GetSearcher("InternalSearcher");
+ return eMgr.GetSearcher(Constants.Examine.InternalIndexer);
}
catch (FileNotFoundException)
{
@@ -411,30 +412,17 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
try
{
//first check in Examine as this is WAY faster
- var criteria = searchProvider.CreateSearchCriteria("media");
+ var criteria = searchProvider.CreateCriteria("media");
- var filter = criteria.ParentId(parentId).Not().Field(UmbracoContentIndexer.IndexPathFieldName, "-1,-21,".MultipleCharacterWildcard());
+ var filter = criteria.ParentId(parentId).Not().Field(BaseUmbracoIndexer.IndexPathFieldName, "-1,-21,".MultipleCharacterWildcard());
//the above filter will create a query like this, NOTE: That since the use of the wildcard, it automatically escapes it in Lucene.
//+(+parentId:3113 -__Path:-1,-21,*) +__IndexType:media
- ISearchResults results;
+ //sort with the Sort field
+ var results = searchProvider.Find(
+ filter.And().OrderBy(new SortableField("sortOrder", SortType.Int)).Compile());
- //we want to check if the indexer for this searcher has "sortOrder" flagged as sortable.
- //if so, we'll use Lucene to do the sorting, if not we'll have to manually sort it (slower).
- var indexer = GetIndexProviderSafe();
- var useLuceneSort = indexer != null && indexer.IndexerData.StandardFields.Any(x => x.Name.InvariantEquals("sortOrder") && x.EnableSorting);
- if (useLuceneSort)
- {
- //we have a sortOrder field declared to be sorted, so we'll use Examine
- results = searchProvider.Search(
- filter.And().OrderBy(new SortableField("sortOrder", SortType.Int)).Compile());
- }
- else
- {
- results = searchProvider.Search(filter.Compile());
- }
-
- if (results.Any())
+ if (results.Any())
{
// var medias = results.Select(ConvertFromSearchResult);
var medias = results.Select(x =>
@@ -446,7 +434,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
return CreateFromCacheValues(cacheValues);
});
- return useLuceneSort ? medias : medias.OrderBy(x => x.SortOrder);
+ return medias;
}
else
{
@@ -562,17 +550,13 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
LoadedFromExamine = fromExamine;
ValidateAndSetProperty(valueDictionary, val => _id = int.Parse(val), "id", "nodeId", "__NodeId"); //should validate the int!
- ValidateAndSetProperty(valueDictionary, val => _key = Guid.Parse(val), "key");
- // wtf are we dealing with templates for medias?!
- ValidateAndSetProperty(valueDictionary, val => _templateId = int.Parse(val), "template", "templateId");
+ ValidateAndSetProperty(valueDictionary, val => _key = Guid.Parse(val), "key");
ValidateAndSetProperty(valueDictionary, val => _sortOrder = int.Parse(val), "sortOrder");
ValidateAndSetProperty(valueDictionary, val => _name = val, "nodeName", "__nodeName");
ValidateAndSetProperty(valueDictionary, val => _urlName = val, "urlName");
- ValidateAndSetProperty(valueDictionary, val => _documentTypeAlias = val, "nodeTypeAlias", UmbracoContentIndexer.NodeTypeAliasFieldName);
+ ValidateAndSetProperty(valueDictionary, val => _documentTypeAlias = val, "nodeTypeAlias", LuceneIndexer.NodeTypeAliasFieldName);
ValidateAndSetProperty(valueDictionary, val => _documentTypeId = int.Parse(val), "nodeType");
- ValidateAndSetProperty(valueDictionary, val => _writerName = val, "writerName");
ValidateAndSetProperty(valueDictionary, val => _creatorName = val, "creatorName", "writerName"); //this is a bit of a hack fix for: U4-1132
- ValidateAndSetProperty(valueDictionary, val => _writerId = int.Parse(val), "writerID");
ValidateAndSetProperty(valueDictionary, val => _creatorId = int.Parse(val), "creatorID", "writerID"); //this is a bit of a hack fix for: U4-1132
ValidateAndSetProperty(valueDictionary, val => _path = val, "path", "__Path");
ValidateAndSetProperty(valueDictionary, val => _createDate = ParseDateTimeValue(val), "createDate");
@@ -668,16 +652,12 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
public override Guid Key { get { return _key; } }
- public override int TemplateId
- {
- get
- {
- //TODO: should probably throw a not supported exception since media doesn't actually support this.
- return _templateId;
- }
- }
+ public override int TemplateId
+ {
+ get { return 0; }
+ }
- public override int SortOrder
+ public override int SortOrder
{
get { return _sortOrder; }
}
@@ -704,7 +684,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
public override string WriterName
{
- get { return _writerName; }
+ get { return _creatorName; }
}
public override string CreatorName
@@ -714,7 +694,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
public override int WriterId
{
- get { return _writerId; }
+ get { return _creatorId; }
}
public override int CreatorId
@@ -739,7 +719,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
public override Guid Version
{
- get { return _version; }
+ get { return Guid.Empty; }
}
public override int Level
@@ -808,20 +788,16 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
private readonly List _keysAdded = new List();
private int _id;
private Guid _key;
- private int _templateId;
private int _sortOrder;
private string _name;
private string _urlName;
private string _documentTypeAlias;
- private int _documentTypeId;
- private string _writerName;
+ private int _documentTypeId;
private string _creatorName;
- private int _writerId;
private int _creatorId;
private string _path;
private DateTime _createDate;
private DateTime _updateDate;
- private Guid _version;
private int _level;
private readonly ICollection _properties;
private readonly PublishedContentType _contentType;
diff --git a/src/Umbraco.Web/Search/ExamineEvents.cs b/src/Umbraco.Web/Search/ExamineEvents.cs
index f2f968801e..7e6a72e8ca 100644
--- a/src/Umbraco.Web/Search/ExamineEvents.cs
+++ b/src/Umbraco.Web/Search/ExamineEvents.cs
@@ -13,8 +13,6 @@ using Umbraco.Core.Models;
using Umbraco.Core.Sync;
using Umbraco.Web.Cache;
using UmbracoExamine;
-using Content = umbraco.cms.businesslogic.Content;
-using Document = umbraco.cms.businesslogic.web.Document;
namespace Umbraco.Web.Search
{
@@ -51,7 +49,6 @@ namespace Umbraco.Web.Search
CacheRefresherBase.CacheUpdated += PublishedPageCacheRefresherCacheUpdated;
CacheRefresherBase.CacheUpdated += MediaCacheRefresherCacheUpdated;
CacheRefresherBase.CacheUpdated += MemberCacheRefresherCacheUpdated;
- CacheRefresherBase.CacheUpdated += ContentTypeCacheRefresherCacheUpdated;
var contentIndexer = ExamineManager.Instance.IndexProviderCollection["InternalIndexer"] as UmbracoContentIndexer;
if (contentIndexer != null)
@@ -65,24 +62,6 @@ namespace Umbraco.Web.Search
}
}
- ///
- /// This is used to refresh content indexers IndexData based on the DataService whenever a content type is changed since
- /// properties may have been added/removed
- ///
- ///
- ///
- ///
- /// See: http://issues.umbraco.org/issue/U4-4798
- ///
- static void ContentTypeCacheRefresherCacheUpdated(ContentTypeCacheRefresher sender, CacheRefresherEventArgs e)
- {
- var indexersToUpdated = ExamineManager.Instance.IndexProviderCollection.OfType();
- foreach (var provider in indexersToUpdated)
- {
- provider.RefreshIndexerDataFromDataService();
- }
- }
-
static void MemberCacheRefresherCacheUpdated(MemberCacheRefresher sender, CacheRefresherEventArgs e)
{
switch (e.MessageType)
diff --git a/src/Umbraco.Web/Search/ExamineIndexerModel.cs b/src/Umbraco.Web/Search/ExamineIndexerModel.cs
index 4fb557d318..c19dc97580 100644
--- a/src/Umbraco.Web/Search/ExamineIndexerModel.cs
+++ b/src/Umbraco.Web/Search/ExamineIndexerModel.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Runtime.Serialization;
using Examine;
@@ -8,8 +9,8 @@ namespace Umbraco.Web.Search
[DataContract(Name = "indexer", Namespace = "")]
public class ExamineIndexerModel : ExamineSearcherModel
{
- [DataMember(Name = "indexCriteria")]
- public IIndexCriteria IndexCriteria { get; set; }
+ [DataMember(Name = "fieldDefinitions")]
+ public IEnumerable FieldDefinitions { get; set; }
///
/// The number of docs in the index
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 8834ea4609..793411d8c1 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -114,7 +114,7 @@
..\packages\dotless.1.4.1.0\lib\dotless.Core.dll
- ..\packages\Examine.2.0.0-beta021\lib\net45\Examine.dll
+ ..\packages\Examine.2.0.0-beta023\lib\net45\Examine.dll
True
diff --git a/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs b/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs
index 31ef4d23f2..cfde906239 100644
--- a/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs
+++ b/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs
@@ -20,6 +20,9 @@ namespace Umbraco.Web.WebServices
[ValidateAngularAntiForgeryToken]
public class ExamineManagementApiController : UmbracoAuthorizedApiController
{
+ //TODO: Fix all of this for searchers/indexers that are not configured via code (i.e. the core ones once we do that)
+ // We will need to be able to search an index directly without having to go through all of the searchers
+
///
/// Checks if the member internal index is consistent with the data stored in the database
///
@@ -74,7 +77,7 @@ namespace Umbraco.Web.WebServices
///
public IEnumerable GetIndexerDetails()
{
- return ExamineManager.Instance.IndexProviderCollection.Select(CreateModel);
+ return ExamineManager.Instance.IndexProviders.Select(CreateModel);
}
///
@@ -103,7 +106,7 @@ namespace Umbraco.Web.WebServices
return model;
}
- public ISearchResults GetSearchResults(string searcherName, string query, string queryType)
+ public ILuceneSearchResults GetSearchResults(string searcherName, string query, string queryType)
{
if (queryType == null)
{
@@ -112,7 +115,7 @@ namespace Umbraco.Web.WebServices
if (query.IsNullOrWhiteSpace())
- return SearchResults.Empty();
+ return LuceneSearchResults.Empty();
LuceneSearcher searcher;
var msg = ValidateLuceneSearcher(searcherName, out searcher);
@@ -120,11 +123,11 @@ namespace Umbraco.Web.WebServices
{
if (queryType.InvariantEquals("text"))
{
- return searcher.Search(query, false);
+ return searcher.Find(query, false);
}
if (queryType.InvariantEquals("lucene"))
{
- return searcher.Search(searcher.CreateSearchCriteria().RawQuery(query));
+ return searcher.Find(searcher.CreateCriteria().RawQuery(query));
}
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
@@ -136,13 +139,14 @@ namespace Umbraco.Web.WebServices
///
public HttpResponseMessage PostOptimizeIndex(string indexerName)
{
- LuceneIndexer indexer;
+ IExamineIndexer indexer;
var msg = ValidateLuceneIndexer(indexerName, out indexer);
- if (msg.IsSuccessStatusCode)
+ var luceneIndexer = indexer as LuceneIndexer;
+ if (luceneIndexer != null && msg.IsSuccessStatusCode)
{
try
{
- indexer.OptimizeIndex();
+ luceneIndexer.OptimizeIndex();
}
catch (Exception ex)
{
@@ -225,7 +229,7 @@ namespace Umbraco.Web.WebServices
//if its still there then it's not done
return found != null
? null
- : CreateModel(indexer);
+ : CreateModel(new KeyValuePair(indexerName, indexer));
}
throw new HttpResponseException(msg);
}
@@ -242,19 +246,19 @@ namespace Umbraco.Web.WebServices
if (msg.IsSuccessStatusCode)
{
var isOptimized = indexer.IsIndexOptimized();
- return !isOptimized
+ return isOptimized == false
? null
- : CreateModel(indexer);
+ : CreateModel(new KeyValuePair(indexerName, indexer));
}
throw new HttpResponseException(msg);
}
- private ExamineIndexerModel CreateModel(BaseIndexProvider indexer)
+ private ExamineIndexerModel CreateModel(KeyValuePair indexer)
{
var indexerModel = new ExamineIndexerModel()
{
- IndexCriteria = indexer.IndexerData,
- Name = indexer.Name
+ FieldDefinitions = indexer.Value.FieldDefinitions,
+ Name = indexer.Key
};
var props = TypeHelper.CachedDiscoverableProperties(indexer.GetType(), mustWrite: false)
//ignore these properties
@@ -266,13 +270,13 @@ namespace Umbraco.Web.WebServices
var val = p.GetValue(indexer, null);
if (val == null)
{
- LogHelper.Warn("Property value was null when setting up property on indexer: " + indexer.Name + " property: " + p.Name);
+ LogHelper.Warn("Property value was null when setting up property on indexer: " + indexer.Key + " property: " + p.Name);
val = string.Empty;
}
indexerModel.ProviderProperties.Add(p.Name, val.ToString());
}
- var luceneIndexer = indexer as LuceneIndexer;
+ var luceneIndexer = indexer.Value as LuceneIndexer;
if (luceneIndexer != null)
{
indexerModel.IsLuceneIndex = true;
@@ -319,24 +323,17 @@ namespace Umbraco.Web.WebServices
return response1;
}
- private HttpResponseMessage ValidateLuceneIndexer(string indexerName, out LuceneIndexer indexer)
- {
- if (ExamineManager.Instance.IndexProviderCollection.Any(x => x.Name == indexerName))
- {
- indexer = ExamineManager.Instance.IndexProviderCollection[indexerName] as LuceneIndexer;
- if (indexer == null)
- {
- var response1 = Request.CreateResponse(HttpStatusCode.BadRequest);
- response1.Content = new StringContent(string.Format("The indexer {0} is not of type {1}", indexerName, typeof(LuceneIndexer)));
- response1.ReasonPhrase = "Wrong Indexer Type";
- return response1;
- }
+ private HttpResponseMessage ValidateLuceneIndexer(string indexerName, out T indexer)
+ where T : class, IExamineIndexer
+ {
+ indexer = null;
+
+ if (ExamineManager.Instance.IndexProviders.ContainsKey(indexerName))
+ {
//return Ok!
return Request.CreateResponse(HttpStatusCode.OK);
}
-
- indexer = null;
-
+
var response = Request.CreateResponse(HttpStatusCode.BadRequest);
response.Content = new StringContent(string.Format("No indexer found with name = {0}", indexerName));
response.ReasonPhrase = "Indexer Not Found";
diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config
index a267cb99ce..5b6feac615 100644
--- a/src/Umbraco.Web/packages.config
+++ b/src/Umbraco.Web/packages.config
@@ -3,7 +3,7 @@
-
+
diff --git a/src/UmbracoExamine/BaseUmbracoIndexer.cs b/src/UmbracoExamine/BaseUmbracoIndexer.cs
index ff4e13de13..f37116e037 100644
--- a/src/UmbracoExamine/BaseUmbracoIndexer.cs
+++ b/src/UmbracoExamine/BaseUmbracoIndexer.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Linq;
using System.Text;
using Examine.LuceneEngine.Config;
@@ -33,8 +34,7 @@ namespace UmbracoExamine
///
/// Used to store the path of a content object
///
- public const string IndexPathFieldName = "__Path";
- public const string NodeTypeAliasFieldName = "__NodeTypeAlias";
+ public const string IndexPathFieldName = "__Path";
public const string IconFieldName = "__Icon";
public const string PublishedFieldName = "__Published";
///
@@ -65,7 +65,7 @@ namespace UmbracoExamine
ProfilingLogger = profilingLogger;
}
- private bool _configBased = false;
+ private readonly bool _configBased = false;
private readonly LocalTempStorageIndexer _localTempStorageIndexer = new LocalTempStorageIndexer();
///
@@ -100,7 +100,7 @@ namespace UmbracoExamine
protected ProfilingLogger ProfilingLogger { get; private set; }
///
- /// Overridden to ensure that
+ /// Overridden to ensure that the umbraco system field definitions are in place
///
///
///
@@ -114,6 +114,7 @@ namespace UmbracoExamine
new FieldDefinition("writerID", FieldDefinitionTypes.Integer),
new FieldDefinition("creatorID", FieldDefinitionTypes.Integer),
new FieldDefinition("sortOrder", FieldDefinitionTypes.Integer),
+ new FieldDefinition("template", FieldDefinitionTypes.Integer),
new FieldDefinition("createDate", FieldDefinitionTypes.DateTime),
new FieldDefinition("updateDate", FieldDefinitionTypes.DateTime),
@@ -146,9 +147,8 @@ namespace UmbracoExamine
}
}
- ///
- /// If true, the IndexingActionHandler will be run to keep the default index up to date.
- ///
+ [Obsolete("This should not be used, it is used by the configuration based indexes but instead to disable Examine event handlers use the ExamineEvents class instead.")]
+ [EditorBrowsable(EditorBrowsableState.Never)]
public bool EnableDefaultEventHandler { get; protected set; }
///
@@ -164,6 +164,9 @@ namespace UmbracoExamine
///
///
///
+ ///
+ /// This is ONLY used for configuration based indexes
+ ///
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
EnableDefaultEventHandler = true; //set to true by default
@@ -201,7 +204,7 @@ namespace UmbracoExamine
#endregion
- public override Lucene.Net.Store.Directory GetLuceneDirectory()
+ public override Directory GetLuceneDirectory()
{
//if temp local storage is configured use that, otherwise return the default
if (UseTempStorage)
@@ -213,19 +216,6 @@ namespace UmbracoExamine
}
- /////
- ///// Override to check if we can actually initialize.
- /////
- /////
- /////
- ///// This check is required since the base examine lib will try to check this method on app startup. If the app
- ///// is not ready then we need to deal with it otherwise the base class will throw exceptions since we've bypassed initialization.
- /////
- //public override bool IndexExists()
- //{
- // return base.IndexExists();
- //}
-
///
/// override to check if we can actually initialize.
///
@@ -254,11 +244,11 @@ namespace UmbracoExamine
base.IndexAll(type);
}
}
-
+
public override void IndexItems(IEnumerable nodes)
{
if (CanInitialize())
- {
+ {
base.IndexItems(nodes);
}
}
@@ -298,8 +288,6 @@ namespace UmbracoExamine
}
}
- #region Protected
-
///
/// Returns true if the Umbraco application is in a state that we can initialize the examine indexes
///
@@ -334,104 +322,57 @@ namespace UmbracoExamine
IndexAll(t);
}
}
-
- /////
- ///// Builds an xpath statement to query against Umbraco data for the index type specified, then
- ///// initiates the re-indexing of the data matched.
- /////
- /////
- //protected override void PerformIndexAll(string type)
- //{
- // //NOTE: the logic below is ONLY used for published content, for media and members and non-published content, this method is overridden
- // // and we query directly against the umbraco service layer.
-
- // if (SupportedTypes.Contains(type) == false)
- // return;
-
- // var xPath = "//*[(number(@id) > 0 and (@isDoc or @nodeTypeAlias)){0}]"; //we'll add more filters to this below if needed
-
- // var sb = new StringBuilder();
-
- // //create the xpath statement to match node type aliases if specified
- // if (IndexerData.IncludeNodeTypes.Any())
- // {
- // sb.Append("(");
- // foreach (var field in IndexerData.IncludeNodeTypes)
- // {
- // //this can be used across both schemas
- // const string nodeTypeAlias = "(@nodeTypeAlias='{0}' or (count(@nodeTypeAlias)=0 and name()='{0}'))";
-
- // sb.Append(string.Format(nodeTypeAlias, field));
- // sb.Append(" or ");
- // }
- // sb.Remove(sb.Length - 4, 4); //remove last " or "
- // sb.Append(")");
- // }
-
- // //create the xpath statement to match all children of the current node.
- // if (IndexerData.ParentNodeId.HasValue && IndexerData.ParentNodeId.Value > 0)
- // {
- // if (sb.Length > 0)
- // sb.Append(" and ");
- // sb.Append("(");
- // sb.Append("contains(@path, '," + IndexerData.ParentNodeId.Value + ",')"); //if the path contains comma - id - comma then the nodes must be a child
- // sb.Append(")");
- // }
-
- // //create the full xpath statement to match the appropriate nodes. If there is a filter
- // //then apply it, otherwise just select all nodes.
- // var filter = sb.ToString();
- // xPath = string.Format(xPath, filter.Length > 0 ? " and " + filter : "");
-
- // //raise the event and set the xpath statement to the value returned
- // var args = new IndexingNodesEventArgs(IndexerData, xPath, type);
- // OnNodesIndexing(args);
- // if (args.Cancel)
- // {
- // return;
- // }
-
- // xPath = args.XPath;
-
- // ProfilingLogger.Logger.Debug(GetType(), "({0}) PerformIndexAll with XPATH: {1}", () => Name, () => xPath);
-
- // AddNodesToIndex(xPath, type);
- //}
-
- #endregion
-
+
+ ///
+ /// overridden for logging
+ ///
+ ///
protected override void OnIndexingError(IndexingErrorEventArgs e)
{
ProfilingLogger.Logger.Error(GetType(), e.Message, e.Exception);
-
base.OnIndexingError(e);
}
+ ///
+ /// Override for logging
+ ///
+ ///
+ protected override void OnIgnoringIndexItem(IndexItemEventArgs e)
+ {
+ ProfilingLogger.Logger.Debug(GetType(), "OnIgnoringIndexItem {0} with type {1}", () => e.IndexItem.ValueSet.Id, () => e.IndexItem.ValueSet.IndexCategory);
+ base.OnIgnoringIndexItem(e);
+ }
+
///
/// This ensures that the special __Raw_ fields are indexed
///
///
-
protected override void OnDocumentWriting(DocumentWritingEventArgs docArgs)
{
var d = docArgs.Document;
- foreach (var f in docArgs.Fields.Where(x => x.Key.StartsWith(RawFieldPrefix)))
+
+ foreach (var f in docArgs.Values.Values.Where(x => x.Key.StartsWith(RawFieldPrefix)))
{
- d.Add(new Field(
- f.Key,
- f.Value,
- Field.Store.YES,
- Field.Index.NO, //don't index this field, we never want to search by it
- Field.TermVector.NO));
+ if (f.Value.Count > 0)
+ {
+ d.Add(new Field(
+ f.Key,
+ f.Value[0].ToString(),
+ Field.Store.YES,
+ Field.Index.NO, //don't index this field, we never want to search by it
+ Field.TermVector.NO));
+ }
}
+ ProfilingLogger.Logger.Debug(GetType(), "OnDocumentWriting {0} with type {1}", () => docArgs.Values.Id, () => docArgs.Values.ItemType);
+
base.OnDocumentWriting(docArgs);
}
- protected override void OnNodeIndexed(IndexedNodeEventArgs e)
+ protected override void OnItemIndexed(IndexItemEventArgs e)
{
- ProfilingLogger.Logger.Debug(GetType(), "Index created for node {0}", () => e.NodeId);
- base.OnNodeIndexed(e);
+ ProfilingLogger.Logger.Debug(GetType(), "Index created for node {0}", () => e.IndexItem.Id);
+ base.OnItemIndexed(e);
}
protected override void OnIndexDeleted(DeleteIndexEventArgs e)
@@ -440,6 +381,7 @@ namespace UmbracoExamine
base.OnIndexDeleted(e);
}
+ [Obsolete("This is no longer used, index optimization is no longer managed with the LuceneIndexer")]
protected override void OnIndexOptimizing(EventArgs e)
{
ProfilingLogger.Logger.Debug(GetType(), "Index is being optimized");
@@ -456,81 +398,43 @@ namespace UmbracoExamine
base.AddDocument(values);
}
- ///
- /// Overridden for logging.
- ///
- ///
- ///
- protected override void AddSingleNodeToIndex(XElement node, string type)
- {
- ProfilingLogger.Logger.Debug(GetType(), "AddSingleNodeToIndex {0} with type {1}", () => (int)node.Attribute("id"), () => type);
- base.AddSingleNodeToIndex(node, type);
- }
-
protected override void OnTransformingIndexValues(TransformingIndexDataEventArgs e)
{
base.OnTransformingIndexValues(e);
- if (e.OriginalValues.ContainsKey("path"))
+ //ensure special __Path field
+ if (e.OriginalValues.ContainsKey("path") && e.IndexItem.ValueSet.Values.ContainsKey(IndexPathFieldName) == false)
{
e.IndexItem.ValueSet.Values[IndexPathFieldName] = new List