Skip to content

Commit

Permalink
implement ordering, bum umbraco 8.1.5
Browse files Browse the repository at this point in the history
  • Loading branch information
arkadiuszbiel committed Sep 24, 2019
1 parent a44955a commit f5bd035
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 24 deletions.
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# version format
version: 0.2.4.{build}
version: 0.2.5.{build}

image: Visual Studio 2019

Expand Down
2 changes: 1 addition & 1 deletion build/Novicell.Examine.ElasticSearch.proj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<!-- SHARED PROPERTIES -->
<PropertyGroup>
<PackageName>Novicell.Examine.ElasticSearch</PackageName>
<MinUmbracoVersion>8.1.2</MinUmbracoVersion>
<MinUmbracoVersion>8.1.5</MinUmbracoVersion>
<Readme>Novicell.Examine.ElasticSearch is a Custom Search Provider for Umbraco v8</Readme>
<AuthorName>Arkadiusz Biel</AuthorName>
<AuthorUrl>https://github.com/novicell/Novicell.Examine.ElasticSearch/graphs/contributors</AuthorUrl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,13 @@ internal ElasticSearchBooleanOperation(ElasticSearchQuery search)

public override IOrdering OrderBy(params SortableField[] fields)
{
throw new NotImplementedException();
//return _search.OrderBy(fields);

return _search.OrderBy(fields);
}

public override IOrdering OrderByDescending(params SortableField[] fields)
{
throw new NotImplementedException();
//return _search.OrderByDescending(fields);
return _search.OrderByDescending(fields);
}

#endregion
Expand Down
98 changes: 80 additions & 18 deletions source/Novicell.Examine.ElasticSearch/Queries/ElasticSearchQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Nest;
using Novicell.Examine.ElasticSearch.Model;
using Umbraco.Core;
using SortField = Lucene.Net.Search.SortField;
using StandardAnalyzer = Lucene.Net.Analysis.Standard.StandardAnalyzer;
using Version = Lucene.Net.Util.Version;

Expand All @@ -20,15 +21,16 @@ public class ElasticSearchQuery : LuceneSearchQueryBase, IQueryExecutor
{
public readonly ElasticSearchSearcher _searcher;
public string _indexName;
internal readonly List<SortField> SortFields = new List<SortField>();
internal Analyzer DefaultAnalyzer { get; } = new StandardAnalyzer(Version.LUCENE_29);
internal static readonly LuceneSearchOptions EmptyOptions = new LuceneSearchOptions();

public ElasticSearchQuery(ElasticSearchSearcher searcher, string category, string[] fields, BooleanOperation op,
string indexName) : base(category, new StandardAnalyzer(Version.LUCENE_29), fields,
EmptyOptions, op)
{
_searcher = searcher;
_indexName = indexName;

}

public ElasticSearchQuery(ElasticSearchQuery previous, BooleanOperation op)
Expand All @@ -41,16 +43,15 @@ public ElasticSearchQuery(ElasticSearchQuery previous, BooleanOperation op)
public ISearchResults Execute(int maxResults = 500)
{
return new ElasticSearchSearchResults(_searcher._client.Value, Query, _indexName, maxResults);

}

protected override LuceneBooleanOperationBase CreateOp()
protected override LuceneBooleanOperationBase CreateOp()
{
return new ElasticSearchBooleanOperation(this);
}

public override IBooleanOperation Field<T>(string fieldName, T fieldValue)
=> RangeQueryInternal<T>(new[] { fieldName }, fieldValue, fieldValue);
public override IBooleanOperation Field<T>(string fieldName, T fieldValue)
=> RangeQueryInternal<T>(new[] {fieldName}, fieldValue, fieldValue);

public override IBooleanOperation ManagedQuery(string query, string[] fields = null)
{
Expand All @@ -60,16 +61,17 @@ public override IBooleanOperation ManagedQuery(string query, string[] fields = n
var fullTextQuery = FullTextType.GenerateQuery(field, query, DefaultAnalyzer);
Query.Add(fullTextQuery, Occurrence);
}

return new ElasticSearchBooleanOperation(this);
}



public override IBooleanOperation RangeQuery<T>(string[] fields, T? min, T? max, bool minInclusive = true, bool maxInclusive = true)
public override IBooleanOperation RangeQuery<T>(string[] fields, T? min, T? max, bool minInclusive = true,
bool maxInclusive = true)
=> RangeQueryInternal(fields, min, max, minInclusive, maxInclusive);

protected override INestedBooleanOperation FieldNested<T>(string fieldName, T fieldValue)
=> RangeQueryInternal<T>(new[] { fieldName }, fieldValue, fieldValue);
=> RangeQueryInternal<T>(new[] {fieldName}, fieldValue, fieldValue);

protected override INestedBooleanOperation ManagedQueryNested(string query, string[] fields = null)
{
Expand All @@ -79,13 +81,17 @@ protected override INestedBooleanOperation ManagedQueryNested(string query, stri
var fullTextQuery = FullTextType.GenerateQuery(field, query, DefaultAnalyzer);
Query.Add(fullTextQuery, Occurrence);
}

return new ElasticSearchBooleanOperation(this);
}

protected override INestedBooleanOperation RangeQueryNested<T>(string[] fields, T? min, T? max, bool minInclusive = true,
protected override INestedBooleanOperation RangeQueryNested<T>(string[] fields, T? min, T? max,
bool minInclusive = true,
bool maxInclusive = true)
=> RangeQueryInternal(fields, min, max, minInclusive, maxInclusive);
private IIndexFieldValueType FromElasticType(IProperty property){

private IIndexFieldValueType FromElasticType(IProperty property)
{
switch (property.Type.ToLowerInvariant())
{
case "date":
Expand All @@ -104,22 +110,23 @@ private IIndexFieldValueType FromElasticType(IProperty property){
return new FullTextType(property.Name.ToString(), new StandardAnalyzer(Version.LUCENE_CURRENT));
}
}
internal ElasticSearchBooleanOperation RangeQueryInternal<T>(string[] fields, T? min, T? max, bool minInclusive = true, bool maxInclusive = true)

internal ElasticSearchBooleanOperation RangeQueryInternal<T>(string[] fields, T? min, T? max,
bool minInclusive = true, bool maxInclusive = true)
where T : struct
{
Query.Add(new LateBoundQuery(() =>
{

//Strangely we need an inner and outer query. If we don't do this then the lucene syntax returned is incorrect
//since it doesn't wrap in parenthesis properly. I'm unsure if this is a lucene issue (assume so) since that is what
//is producing the resulting lucene string syntax. It might not be needed internally within Lucene since it's an object
//so it might be the ToString() that is the issue.
var outer = new BooleanQuery();
var inner = new BooleanQuery();
var fieldsMapping = _searcher.AllProperties;
foreach (var valueType in fieldsMapping.Where(e=>fields.Contains(e.Key.Name)))

var fieldsMapping = _searcher.AllProperties;

foreach (var valueType in fieldsMapping.Where(e => fields.Contains(e.Key.Name)))
{
if (FromElasticType(valueType.Value) is IIndexRangeValueType<T> type)
{
Expand All @@ -132,9 +139,11 @@ internal ElasticSearchBooleanOperation RangeQueryInternal<T>(string[] fields, T?
}
else
{
throw new InvalidOperationException($"Could not perform a range query on the field {valueType.Key}, it's value type is {valueType.Value.Type}");
throw new InvalidOperationException(
$"Could not perform a range query on the field {valueType.Key}, it's value type is {valueType.Value.Type}");
}
}

outer.Add(inner, Occur.SHOULD);

return outer;
Expand All @@ -143,5 +152,58 @@ internal ElasticSearchBooleanOperation RangeQueryInternal<T>(string[] fields, T?

return new ElasticSearchBooleanOperation(this);
}

private ElasticSearchBooleanOperation OrderByInternal(bool descending, params SortableField[] fields)
{
if (fields == null) throw new ArgumentNullException(nameof(fields));

foreach (var f in fields)
{
var fieldName = f.FieldName;

var defaultSort = SortField.STRING;

switch (f.SortType)
{
case SortType.Score:
defaultSort = SortField.SCORE;
break;
case SortType.DocumentOrder:
defaultSort = SortField.DOC;
break;
case SortType.String:
defaultSort = SortField.STRING;
break;
case SortType.Int:
defaultSort = SortField.INT;
break;
case SortType.Float:
defaultSort = SortField.FLOAT;
break;
case SortType.Long:
defaultSort = SortField.LONG;
break;
case SortType.Double:
defaultSort = SortField.DOUBLE;
break;
case SortType.Short:
defaultSort = SortField.SHORT;
break;
case SortType.Byte:
defaultSort = SortField.BYTE;
break;
default:
throw new ArgumentOutOfRangeException();
}

SortFields.Add(new SortField(fieldName, defaultSort, descending));
}

return new ElasticSearchBooleanOperation(this);
}

public IOrdering OrderBy(params SortableField[] fields) => OrderByInternal(false, fields);

public IOrdering OrderByDescending(params SortableField[] fields) => OrderByInternal(true, fields);
}
}

0 comments on commit f5bd035

Please sign in to comment.