From a073091b4f8e4f5dee3eb140854424f46bdb5ef2 Mon Sep 17 00:00:00 2001 From: Davey Boyle Date: Thu, 24 Mar 2022 14:58:14 +0000 Subject: [PATCH] Added Solr adaptor --- Lucinq.Lucene30/Adapters/LuceneAdapter.cs | 10 + Lucinq.Solr/Adapters/SolrSearchAdapter.cs | 257 +++- Lucinq.Solr/Adapters/SolrSearchModel.cs | 12 +- Lucinq.Solr/Lucinq.Solr.csproj | 34 +- Lucinq.Solr/Querying/ClauseOperator.cs | 9 + Lucinq.Solr/Querying/ISolrSearchResult.cs | 4 +- Lucinq.Solr/Querying/SolrSearch.cs | 14 +- Lucinq.Solr/Querying/SolrSearchDetails.cs | 4 +- Lucinq.Solr/Querying/SolrSearchResult.cs | 108 +- Lucinq.Solr/packages.config | 13 +- Lucinq/Querying/QueryBuilderIndividual.cs | 2 +- .../UnitTests/EquivalencyTests.cs | 30 +- Unit Tests/Lucinq.Solr.UnitTests/App.config | 2 +- .../IntegrationTests/BaseTestFixture.cs | 277 ++-- .../IntegrationTests/BasicCollectorTests.cs | 98 -- .../IntegrationTests/BasicTests..cs | 730 +++++----- .../IntegrationTests/DateFieldTests.cs | 100 -- .../FilesystemDirectoryTests.cs | 32 - .../IntegrationTests/IndexRebuilder.cs | 406 +++--- .../IntegrationTests/PrefixTests.cs | 78 -- .../Lucinq.Solr.UnitTests.csproj | 34 +- .../UnitTests/ConceptTests.cs | 263 ---- .../UnitTests/EquivalencyTests.cs | 1185 ++++++++--------- .../UnitTests/ItemResultTests.cs | 167 --- .../Lucinq.Solr.UnitTests/packages.config | 6 +- .../UnitTests/EquivalencyTests.cs | 2 - 26 files changed, 1530 insertions(+), 2347 deletions(-) create mode 100644 Lucinq.Solr/Querying/ClauseOperator.cs delete mode 100644 Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/BasicCollectorTests.cs delete mode 100644 Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/DateFieldTests.cs delete mode 100644 Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/FilesystemDirectoryTests.cs delete mode 100644 Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/PrefixTests.cs delete mode 100644 Unit Tests/Lucinq.Solr.UnitTests/UnitTests/ConceptTests.cs delete mode 100644 Unit Tests/Lucinq.Solr.UnitTests/UnitTests/ItemResultTests.cs diff --git a/Lucinq.Lucene30/Adapters/LuceneAdapter.cs b/Lucinq.Lucene30/Adapters/LuceneAdapter.cs index be319a8..5a26944 100644 --- a/Lucinq.Lucene30/Adapters/LuceneAdapter.cs +++ b/Lucinq.Lucene30/Adapters/LuceneAdapter.cs @@ -84,12 +84,22 @@ protected virtual void Visit(LucinqQuery query, BooleanQuery booleanQuery = null { VisitLongRange(longQuery, booleanQuery); } + else if (query is LucinqRangeQuery floatQuery) + { + VisitFloatRange(floatQuery, booleanQuery); + } else if (query is LucinqRangeQuery termRangeQuery) { VisitTermRange(termRangeQuery, booleanQuery); } } + private void VisitFloatRange(LucinqRangeQuery query, BooleanQuery booleanQuery) + { + NumericRangeQuery nativeQuery = NumericRangeQuery.NewFloatRange(query.Field, query.PrecisionStep ?? 1, query.Lower, query.Upper, query.IncludeMin, query.IncludeMax); + AddQuery(query, booleanQuery, nativeQuery); + } + protected virtual void VisitTermRange(LucinqRangeQuery query, BooleanQuery booleanQuery) { TermRangeQuery nativeQuery = new TermRangeQuery(query.Field, query.Lower, query.Upper, query.IncludeMin, query.IncludeMax); diff --git a/Lucinq.Solr/Adapters/SolrSearchAdapter.cs b/Lucinq.Solr/Adapters/SolrSearchAdapter.cs index a3da87e..3f8d674 100644 --- a/Lucinq.Solr/Adapters/SolrSearchAdapter.cs +++ b/Lucinq.Solr/Adapters/SolrSearchAdapter.cs @@ -2,10 +2,12 @@ { using System; using System.Collections.Generic; + using System.Linq; using System.Text; using Core.Adapters; using Core.Enums; using Core.Querying; + using SolrNet; public class SolrSearchAdapter : IProviderAdapter { @@ -17,7 +19,6 @@ public virtual SolrSearchModel Adapt(LucinqQueryModel model) Visit(model.Query); Visit(model.Sort); Visit(model.Filter); - NativeModel.SearchParameters.Filter = NativeModel.FilterBuilder.ToString(); return NativeModel; } @@ -28,24 +29,63 @@ protected virtual void Visit(LucinqSort sort) return; } - NativeModel.SearchParameters.OrderBy = new List(); + if (sort?.SortFields == null || sort.SortFields.Length == 0) + { + return; + } + foreach (var sortField in sort.SortFields) { - string orderBy = sortField.FieldName; - if (sortField.SortDescending) - { - orderBy += " desc"; - } - NativeModel.SearchParameters.OrderBy.Add(orderBy); + Order order = sortField.SortDescending ? Order.DESC : Order.ASC; + + NativeModel.QueryOptions.OrderBy.Add(new SortOrder(sortField.FieldName, order)); + } } protected virtual void Visit(LucinqFilter filter) { + if (filter == null) + { + return; + } + + string comparator; + string filterString; + switch (filter.Comparator) + { + case Comparator.Equals: + filterString = $"{filter.Field}:{filter.Value}"; + break; + case Comparator.NotEquals: + filterString = $"{filter.Field}:!{filter.Value}"; + break; + case Comparator.GreaterThan: + filterString = $"{filter.Field}:{{{filter.Value} TO * ]"; + break; + case Comparator.GreaterThanEquals: + filterString = $"{filter.Field}:[{filter.Value} TO * ]"; + break; + case Comparator.LessThan: + filterString = $"{filter.Field}:[* TO {filter.Value} }}"; + break; + case Comparator.LessThanEquals: + filterString = $"{filter.Field}:[* TO {filter.Value} ]"; + break; + default: + filterString = $"{filter.Field}:{filter.Value}"; + break; + } + + if (NativeModel.FilterBuilder.Length > 0) + { + NativeModel.FilterBuilder.Append(" and "); + } + NativeModel.FilterBuilder.Append(filterString); } - protected virtual void Visit(LucinqQuery query, StringBuilder stringBuilder = null) + protected virtual void Visit(LucinqQuery query, StringBuilder stringBuilder = null, bool omitLeadingOperator = false) { if (stringBuilder == null) { @@ -55,14 +95,15 @@ protected virtual void Visit(LucinqQuery query, StringBuilder stringBuilder = nu { VisitPrimary(queryRoot, stringBuilder); } - else if (query is LucinqOrQuery orQuery) + else if (query is LucinqAndQuery andQuery) { - VisitOr(orQuery, stringBuilder); + VisitAnd(andQuery, stringBuilder, omitLeadingOperator); } - else if (query is LucinqAndQuery andQuery) + else if (query is LucinqOrQuery orQuery) { - VisitAnd(andQuery, stringBuilder); + VisitOr(orQuery, stringBuilder, omitLeadingOperator); } + else if (query is LucinqFuzzyQuery fuzzyQuery) { VisitFuzzy(fuzzyQuery, stringBuilder); @@ -103,50 +144,64 @@ protected virtual void Visit(LucinqQuery query, StringBuilder stringBuilder = nu { VisitTermRange(termRangeQuery, stringBuilder); } + + } protected virtual void VisitTermRange(LucinqRangeQuery query, StringBuilder stringBuilder) { - string lowerOperator = query.IncludeMin ? "ge" : "gt"; - string lower = !String.IsNullOrEmpty(query.Lower) ? $"{query.Field} {lowerOperator} '{query.Lower}'" : String.Empty; + string lowerOperator = query.IncludeMin ? "[" : "{"; + string lower = !String.IsNullOrEmpty(query.Lower) ? $"{lowerOperator}{query.Lower}" : String.Empty; + + string upperOperator = query.IncludeMin ? "]" : "}"; + string upper = !String.IsNullOrEmpty(query.Upper) ? $"{query.Upper}{upperOperator}" : String.Empty; - string upperOperator = query.IncludeMin ? "le" : "lt"; - string upper = !String.IsNullOrEmpty(query.Upper) ? $"{query.Field} {upperOperator} '{query.Upper}'" : String.Empty; - NativeModel.FilterBuilder.Append($"({lower} and {upper})"); + string value = $"{query.Field}:{lower} TO {upper}"; + + NativeModel.FilterBuilder.Append($"{value}"); } protected virtual void VisitIntRange(LucinqRangeQuery query, StringBuilder stringBuilder) { - string lowerOperator = query.IncludeMin ? "ge" : "gt"; - string lower = !String.IsNullOrEmpty(query.Lower.ToString()) ? $"{query.Field} {lowerOperator} {query.Lower.ToString()}" : String.Empty; + string lowerOperator = query.IncludeMin ? "[" : "{"; + string lower = !String.IsNullOrEmpty(query.Lower.ToString()) ? $"{lowerOperator}{query.Lower}" : String.Empty; + + string upperOperator = query.IncludeMin ? "]" : "}"; + string upper = !String.IsNullOrEmpty(query.Upper.ToString()) ? $"{query.Upper}{upperOperator}" : String.Empty; - string upperOperator = query.IncludeMin ? "le" : "lt"; - string upper = !String.IsNullOrEmpty(query.Upper.ToString()) ? $"{query.Field} {upperOperator} {query.Upper.ToString()}" : String.Empty; - NativeModel.FilterBuilder.Append($"({lower} and {upper})"); + string value = $"{query.Field}:{lower} TO {upper}"; + + NativeModel.FilterBuilder.Append(value); } protected virtual void VisitLongRange(LucinqRangeQuery query, StringBuilder stringBuilder) { - string lowerOperator = query.IncludeMin ? "ge" : "gt"; - string lower = !String.IsNullOrEmpty(query.Lower.ToString()) ? $"{query.Field} {lowerOperator} {query.Lower.ToString()}" : String.Empty; + string lowerOperator = query.IncludeMin ? "[" : "{"; + string lower = !String.IsNullOrEmpty(query.Lower.ToString()) ? $"{lowerOperator}{query.Lower}" : String.Empty; + + string upperOperator = query.IncludeMin ? "]" : "}"; + string upper = !String.IsNullOrEmpty(query.Upper.ToString()) ? $"{query.Upper}{upperOperator}" : String.Empty; - string upperOperator = query.IncludeMin ? "le" : "lt"; - string upper = !String.IsNullOrEmpty(query.Upper.ToString()) ? $"{query.Field} {upperOperator} {query.Upper.ToString()}" : String.Empty; - NativeModel.FilterBuilder.Append($"({lower} and {upper})"); + string value = $"{query.Field}:{lower} TO {upper}"; + + NativeModel.FilterBuilder.Append(value); } protected virtual void VisitDoubleRange(LucinqRangeQuery query, StringBuilder stringBuilder) { - string lowerOperator = query.IncludeMin ? "ge" : "gt"; - string lower = !String.IsNullOrEmpty(query.Lower.ToString()) ? $"{query.Field} {lowerOperator} {query.Lower.ToString()}" : String.Empty; + string lowerOperator = query.IncludeMin ? "[" : "{"; + string lower = !String.IsNullOrEmpty(query.Lower.ToString()) ? $"{lowerOperator}{query.Lower}" : String.Empty; + + string upperOperator = query.IncludeMin ? "]" : "}"; + string upper = !String.IsNullOrEmpty(query.Upper.ToString()) ? $"{query.Upper}{upperOperator}" : String.Empty; - string upperOperator = query.IncludeMin ? "le" : "lt"; - string upper = !String.IsNullOrEmpty(query.Upper.ToString()) ? $"{query.Field} {upperOperator} {query.Upper.ToString()}" : String.Empty; - NativeModel.FilterBuilder.Append($"({lower} and {upper})"); + string value = $"{query.Field}:{lower} TO {upper}"; + + NativeModel.FilterBuilder.Append(value); } protected virtual void VisitKeyword(LucinqKeywordQuery query, StringBuilder stringBuilder) @@ -169,7 +224,7 @@ protected virtual void VisitTerm(LucinqTermQuery query, StringBuilder stringBuil stringBuilder.Append(GetTermQueryString(query, false, stringBuilder)); } - private string GetTermQueryString(LucinqTermQuery query, bool quoteValue, StringBuilder stringBuilder) + private string GetTermQueryString(LucinqTermQuery query, bool quoteValue, StringBuilder stringBuilder, bool fuzzy = false) { string returnString = null; if (stringBuilder.Length > 0) @@ -191,81 +246,159 @@ private string GetTermQueryString(LucinqTermQuery query, bool quoteValue, String } string value = quoteValue ? $"\"{query.SearchTerm.Value}\"" : query.SearchTerm.Value; + if (fuzzy) + { + value += "~"; + } string boostString = query.Boost.HasValue ? $"~{query.Boost.Value}" : String.Empty; returnString += $"{occurrence}{query.SearchTerm.Field}:{value}{boostString}"; return returnString; } - protected virtual void VisitPrimary(LucinqGroupQuery query, StringBuilder stringBuilder) + protected virtual void VisitGroup(LucinqGroupQuery query, StringBuilder stringBuilder, bool omitLeadingOperator = false) { - StringBuilder builder = new StringBuilder(); - bool first = true; - foreach (var subQuery in query.Queries) + + + + if (stringBuilder.Length > 0) { - if (!first) + stringBuilder.Append(" "); + + if (query.Matches == Matches.Always) { - builder.Append(" OR"); + stringBuilder.Append("AND "); + } + else + { + stringBuilder.Append("OR "); } - Visit(subQuery, builder); - first = false; - } - if (stringBuilder.Length > 0) + StringBuilder builder = new StringBuilder(); + + var first = true; + foreach (var subQuery in query.Queries) { - stringBuilder.Append(" "); + + Visit(subQuery, builder); + first = false; } stringBuilder.Append(builder); } - protected virtual void VisitAnd(LucinqAndQuery query, StringBuilder stringBuilder) + protected virtual void VisitPrimary(LucinqGroupQuery query, StringBuilder stringBuilder) { + if (stringBuilder.Length > 0) + { + stringBuilder.Append(" "); + } + StringBuilder builder = new StringBuilder(); bool first = true; foreach (var subQuery in query.Queries) { - if (!first) - { - builder.Append(" AND"); - } - Visit(subQuery, builder); + Visit(subQuery, builder, first); first = false; } - if (stringBuilder.Length > 0) - { - stringBuilder.Append(" "); - } stringBuilder.Append(builder); } - protected virtual void VisitOr(LucinqOrQuery query, StringBuilder stringBuilder) + protected virtual void VisitAnd(LucinqAndQuery query, StringBuilder stringBuilder, bool omitLeadingOperator = false) + { + VisitGroupQuery(query, stringBuilder, omitLeadingOperator, "AND"); + } + + protected virtual void VisitOr(LucinqOrQuery query, StringBuilder stringBuilder, bool omitLeadingOperator = false) { + VisitGroupQuery(query, stringBuilder, omitLeadingOperator, "OR"); + } + + private void VisitGroupQuery(LucinqGroupQuery query, StringBuilder stringBuilder, bool omitLeadingOperator, + string groupSeperator) + { + if (query.Queries.Count == 0 || query.Queries.All(IsRangeQuery)) + { + return; + } + StringBuilder builder = new StringBuilder(); bool first = true; + + if (stringBuilder.Length > 0) + { + builder.Append(" "); + } + + if (!omitLeadingOperator) + { + if (query.Matches == Matches.Always) + { + builder.Append("AND "); + } + else + { + builder.Append("OR "); + } + } + + if (query.Queries.Count > 1) + { + builder.Append("("); + } + foreach (var subQuery in query.Queries) { - if (!first) + if (IsRangeQuery(subQuery)) { - builder.Append(" OR"); + continue; + } + + if (!first && !IsGroupQuery(subQuery)) + { + string subgroupSeperator; + if (subQuery.Matches == Matches.Always) + { + subgroupSeperator = "AND"; + } + else + { + subgroupSeperator = "OR"; + } + builder.Append($" {subgroupSeperator}"); } - Visit(subQuery, builder); - first = false; + Visit(subQuery, builder, first); + first = false; } - if (stringBuilder.Length > 0) + if (query.Queries.Count > 1) { - stringBuilder.Append(" "); + builder.Append(")"); } + stringBuilder.Append(builder); } + protected bool IsRangeQuery(LucinqQuery query) + { + Type rangeQueryType = typeof(LucinqRangeQuery<>); + Type queryType = query.GetType(); + return queryType.IsGenericType && rangeQueryType.IsAssignableFrom(queryType.GetGenericTypeDefinition()); + } + + private static bool IsGroupQuery(LucinqQuery subQuery) + { + return subQuery is LucinqAndQuery || subQuery is LucinqOrQuery; + } + + protected virtual void VisitFuzzy(LucinqFuzzyQuery query, StringBuilder stringBuilder) { + stringBuilder.Append(GetTermQueryString(query, false, stringBuilder, true)); } protected virtual void VisitPhrase(LucinqPhraseQuery query, StringBuilder stringBuilder) diff --git a/Lucinq.Solr/Adapters/SolrSearchModel.cs b/Lucinq.Solr/Adapters/SolrSearchModel.cs index ad3f97b..b3fd3ee 100644 --- a/Lucinq.Solr/Adapters/SolrSearchModel.cs +++ b/Lucinq.Solr/Adapters/SolrSearchModel.cs @@ -1,21 +1,27 @@ namespace Lucinq.Solr.Adapters { + using System.Collections.Generic; using System.Text; - using Microsoft.Azure.Search.Models; + using System.Threading; + using SolrNet; + using SolrNet.Commands.Parameters; public class SolrSearchModel { - public SearchParameters SearchParameters { get; } public StringBuilder QueryBuilder { get; set; } public StringBuilder FilterBuilder { get; set; } + public QueryOptions QueryOptions { get; } + + public bool IncludeTotalNumberOfSearchResults { get; set; } + public SolrSearchModel() { QueryBuilder = new StringBuilder(); FilterBuilder = new StringBuilder(); - SearchParameters = new SearchParameters(); + QueryOptions = new QueryOptions(); } } } diff --git a/Lucinq.Solr/Lucinq.Solr.csproj b/Lucinq.Solr/Lucinq.Solr.csproj index d27c031..d8146f8 100644 --- a/Lucinq.Solr/Lucinq.Solr.csproj +++ b/Lucinq.Solr/Lucinq.Solr.csproj @@ -32,29 +32,17 @@ 4 - - ..\packages\Microsoft.Azure.Search.5.0.3\lib\net452\Microsoft.Azure.Search.dll + + ..\packages\CommonServiceLocator.2.0.2\lib\net45\CommonServiceLocator.dll - - ..\packages\Microsoft.Azure.Search.Common.5.0.3\lib\net452\Microsoft.Azure.Search.Common.dll + + ..\packages\SolrNet.1.0.19\lib\net46\CommonServiceLocator.SolrNet.dll - - ..\packages\Microsoft.Azure.Search.Data.5.0.3\lib\net452\Microsoft.Azure.Search.Data.dll + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll - - ..\packages\Microsoft.Azure.Search.Service.5.0.3\lib\net452\Microsoft.Azure.Search.Service.dll - - - ..\packages\Microsoft.Rest.ClientRuntime.2.3.17\lib\net452\Microsoft.Rest.ClientRuntime.dll - - - ..\packages\Microsoft.Rest.ClientRuntime.Azure.3.3.18\lib\net452\Microsoft.Rest.ClientRuntime.Azure.dll - - - ..\packages\Microsoft.Spatial.7.2.0\lib\portable-net45+win8+wpa81\Microsoft.Spatial.dll - - - ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll + + ..\packages\SolrNet.Core.1.0.19\lib\net46\SolrNet.dll @@ -62,6 +50,9 @@ + + ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll + @@ -71,7 +62,7 @@ - + @@ -89,6 +80,5 @@ - \ No newline at end of file diff --git a/Lucinq.Solr/Querying/ClauseOperator.cs b/Lucinq.Solr/Querying/ClauseOperator.cs new file mode 100644 index 0000000..ea225b6 --- /dev/null +++ b/Lucinq.Solr/Querying/ClauseOperator.cs @@ -0,0 +1,9 @@ +namespace Lucinq.Solr.Querying +{ + public enum ClauseOperator + { + None, + And, + Or + } +} \ No newline at end of file diff --git a/Lucinq.Solr/Querying/ISolrSearchResult.cs b/Lucinq.Solr/Querying/ISolrSearchResult.cs index 7ddae1d..fc7b2cb 100644 --- a/Lucinq.Solr/Querying/ISolrSearchResult.cs +++ b/Lucinq.Solr/Querying/ISolrSearchResult.cs @@ -1,9 +1,9 @@ namespace Lucinq.Solr.Querying { + using System.Collections.Generic; using Core.Interfaces; - using Microsoft.Azure.Search.Models; - public interface ISolrSearchResult : ISearchResult + public interface ISolrSearchResult : ISearchResult> { } } diff --git a/Lucinq.Solr/Querying/SolrSearch.cs b/Lucinq.Solr/Querying/SolrSearch.cs index 7433e44..75311c6 100644 --- a/Lucinq.Solr/Querying/SolrSearch.cs +++ b/Lucinq.Solr/Querying/SolrSearch.cs @@ -1,32 +1,32 @@ namespace Lucinq.Solr.Querying { using System; + using System.Collections.Generic; using System.Diagnostics; using Adapters; using Core.Adapters; using Core.Interfaces; using Core.Querying; using Core.Results; - using Microsoft.Azure.Search.Models; public class SolrSearch : ISolrSearch { public IProviderAdapter Adapter { get; } - protected SolrSearchDetails AzureSearchDetails { get; } + protected SolrSearchDetails SolrSearchDetails { get; } protected string IndexName { get; } #region [ Constructors ] - public SolrSearch(IProviderAdapter adapter, SolrSearchDetails azureSearchDetails, string indexName) + public SolrSearch(IProviderAdapter adapter, SolrSearchDetails solrSearchDetails, string indexName) { Adapter = adapter; - AzureSearchDetails = azureSearchDetails; + SolrSearchDetails = solrSearchDetails; IndexName = indexName; } - public SolrSearch(SolrSearchDetails azureSearchDetails, string indexName) : this(new SolrSearchAdapter(), azureSearchDetails, indexName) + public SolrSearch(SolrSearchDetails solrSearchDetails, string indexName) : this(new SolrSearchAdapter(), solrSearchDetails, indexName) { } @@ -67,7 +67,7 @@ public virtual void Collect(LucinqQueryModel lucinqModel) public virtual ISolrSearchResult Execute(LucinqQueryModel lucinqModel, int noOfResults = Int32.MaxValue - 1) { var nativeModel = Adapter.Adapt(lucinqModel); - return new AzureSearchResult(nativeModel, AzureSearchDetails, IndexName); + return new SolrSearchResult(nativeModel, SolrSearchDetails, IndexName); } public virtual ISolrSearchResult Execute(IQueryBuilder queryBuilder, int noOfResults = Int32.MaxValue - 1) @@ -75,7 +75,7 @@ public virtual ISolrSearchResult Execute(IQueryBuilder queryBuilder, int noOfRes return Execute(queryBuilder.Build(), noOfResults); } - public virtual TItemResult Execute(IQueryBuilder queryBuilder, Func creator, int noOfResults = Int32.MaxValue - 1) where TItemResult : ItemSearchResult + public virtual TItemResult Execute(IQueryBuilder queryBuilder, Func creator, int noOfResults = Int32.MaxValue - 1) where TItemResult : ItemSearchResult, T> { ISolrSearchResult searchResult = Execute(queryBuilder.Build(), noOfResults); return creator(searchResult); diff --git a/Lucinq.Solr/Querying/SolrSearchDetails.cs b/Lucinq.Solr/Querying/SolrSearchDetails.cs index 4dd88b6..e2c6a5b 100644 --- a/Lucinq.Solr/Querying/SolrSearchDetails.cs +++ b/Lucinq.Solr/Querying/SolrSearchDetails.cs @@ -2,13 +2,11 @@ { public class SolrSearchDetails { - public SolrSearchDetails(string searchServiceName, string adminApiKey) + public SolrSearchDetails(string searchServiceName) { SearchServiceName = searchServiceName; - AdminApiKey = adminApiKey; } - public string AdminApiKey { get; } public string SearchServiceName { get; } } diff --git a/Lucinq.Solr/Querying/SolrSearchResult.cs b/Lucinq.Solr/Querying/SolrSearchResult.cs index c754daa..e983422 100644 --- a/Lucinq.Solr/Querying/SolrSearchResult.cs +++ b/Lucinq.Solr/Querying/SolrSearchResult.cs @@ -1,23 +1,26 @@ namespace Lucinq.Solr.Querying { + using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; + using System.Linq; using Adapters; - using Microsoft.Azure.Search; - using Microsoft.Azure.Search.Models; + using CommonServiceLocator; + using SolrNet; + using SolrNet.Impl; - public class AzureSearchResult : ISolrSearchResult + public class SolrSearchResult : ISolrSearchResult { #region [ Fields ] - private int totalHits; - private bool searchExecuted; - private DocumentSearchResult topDocs; + private int totalHits; + private bool searchExecuted; + private IList> topDocs; protected string IndexName { get; } - protected SolrSearchDetails AzureSearchDetails { get; } + protected SolrSearchDetails SolrSearchDetails { get; } protected SolrSearchModel Model { get; } @@ -25,38 +28,38 @@ public class AzureSearchResult : ISolrSearchResult #region [ Constructors ] - public AzureSearchResult(SolrSearchModel model, SolrSearchDetails azureSearchDetails, string indexName) + public SolrSearchResult(SolrSearchModel model, SolrSearchDetails solrSearchDetails, string indexName) { Model = model; - AzureSearchDetails = azureSearchDetails; + SolrSearchDetails = solrSearchDetails; IndexName = indexName; } - #endregion + #endregion - #region [ Properties ] + #region [ Properties ] - public int TotalHits - { - get - { + public int TotalHits + { + get + { ExecuteSearch(null, null); - return totalHits; - } - } + return totalHits; + } + } - public long ElapsedTimeMs { get; set; } + public long ElapsedTimeMs { get; set; } #endregion - #region [ Methods ] + #region [ Methods ] - public virtual IList GetTopItems() - { - ExecuteSearch(null, 30); + public virtual IList> GetTopItems() + { + ExecuteSearch(null, 30); - return topDocs.Results; - } + return topDocs; + } /// /// Gets a range of items on a zero based index @@ -64,7 +67,7 @@ public virtual IList GetTopItems() /// /// /// - public virtual IList GetRange(int start, int end) + public virtual IList> GetRange(int start, int end) { if (start < 0) { @@ -75,42 +78,55 @@ public virtual IList GetRange(int start, int end) ExecuteSearch(start, take); - return topDocs.Results; + return topDocs; } private void ExecuteSearch(int? skip, int? take) - { + { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - Model.SearchParameters.Top = take; - Model.SearchParameters.Skip = skip; - Model.SearchParameters.IncludeTotalResultCount = true; + if (skip == null) + { + skip = 0; + } + Model.QueryOptions.StartOrCursor = new StartOrCursor.Start((int)skip); + Model.QueryOptions.Rows = take; - using (ISearchServiceClient serviceClient = new SearchServiceClient(AzureSearchDetails.SearchServiceName, new SearchCredentials(AzureSearchDetails.AdminApiKey))) - { - ISearchIndexClient indexClient = serviceClient.Indexes.GetClient(IndexName); - topDocs = indexClient.Documents.Search(Model.QueryBuilder.ToString(), Model.SearchParameters); - totalHits = (int) (topDocs?.Count); - } - stopwatch.Stop(); - ElapsedTimeMs = stopwatch.ElapsedMilliseconds; - } + Model.IncludeTotalNumberOfSearchResults = true; + var solr = ServiceLocator.Current.GetInstance>>(); - #endregion + if (Model.QueryBuilder.ToString() == String.Empty) + { + Model.QueryBuilder.Append("*:*"); + } + + var solrQuery = new SolrQuery(Model.QueryBuilder.ToString()); + Model.QueryOptions.FilterQueries.Add(new SolrQuery(Model.FilterBuilder.ToString())); + + SolrQueryResults> results = solr.Query(solrQuery, Model.QueryOptions); + + topDocs = results; + totalHits = topDocs.Count; + + stopwatch.Stop(); + ElapsedTimeMs = stopwatch.ElapsedMilliseconds; + } + + #endregion #region [ IEnumerable Methods ] - public IEnumerator GetEnumerator() + public IEnumerator> GetEnumerator() { return GetTopItems().GetEnumerator(); - } + } - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); } #endregion diff --git a/Lucinq.Solr/packages.config b/Lucinq.Solr/packages.config index 77578fc..b8a2648 100644 --- a/Lucinq.Solr/packages.config +++ b/Lucinq.Solr/packages.config @@ -1,11 +1,8 @@  - - - - - - - - + + + + + \ No newline at end of file diff --git a/Lucinq/Querying/QueryBuilderIndividual.cs b/Lucinq/Querying/QueryBuilderIndividual.cs index f777d1a..98d7e40 100644 --- a/Lucinq/Querying/QueryBuilderIndividual.cs +++ b/Lucinq/Querying/QueryBuilderIndividual.cs @@ -318,7 +318,7 @@ public virtual void NumericRange(string fieldName, long minValue, long maxValue, public virtual void DateRange(string fieldName, DateTime minValue, DateTime maxValue, Matches occur = Matches.NotSet, float? boost = null, int precisionStep = Int32.MaxValue, bool includeMin = true, bool includeMax = true, string key = null) { - LucinqRangeQuery rangeQuery = new LucinqRangeQuery(fieldName, precisionStep, minValue.Ticks, maxValue.Ticks, includeMin, includeMax, LucinqConstants.AdapterKeys.FloatRangeQuery) + LucinqRangeQueryrangeQuery = new LucinqRangeQuery(fieldName, precisionStep, minValue.Ticks, maxValue.Ticks, includeMin, includeMax, LucinqConstants.AdapterKeys.LongRangeQuery) { Matches = occur }; diff --git a/Unit Tests/Lucinq.AzureSearch.UnitTests/UnitTests/EquivalencyTests.cs b/Unit Tests/Lucinq.AzureSearch.UnitTests/UnitTests/EquivalencyTests.cs index 2179b65..c707e4b 100644 --- a/Unit Tests/Lucinq.AzureSearch.UnitTests/UnitTests/EquivalencyTests.cs +++ b/Unit Tests/Lucinq.AzureSearch.UnitTests/UnitTests/EquivalencyTests.cs @@ -345,7 +345,7 @@ public void CaseSensitiveNonMandatoryWildCard() [Test] public void CaseInsensitiveWildCards() { - string queryString = "+_name:value* AND +_name:value2*"; + string queryString = "( +_name:value* AND +_name:value2*)"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.WildCards("_name", new []{"Value*", "Value2*"})); @@ -505,7 +505,7 @@ public void CaseInsensitiveKeywords() { QueryBuilder builder = new QueryBuilder(); - string queryString = "+_name:\"value\" AND +_name:\"value2\" AND +_name:\"value3\""; + string queryString = "( +_name:\"value\" AND +_name:\"value2\" AND +_name:\"value3\")"; builder.Setup(x => x.Keywords("_name", new []{"Value", "Value2", "Value3"})); LucinqQueryModel replacementQuery = builder.Build(); @@ -524,7 +524,7 @@ public void CaseInsensitiveKeywords() [Test] public void IntegerRange() { - string queryString = "(field ge 0 and field le 10)"; + string queryString = "field ge 0 and field le 10"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.NumericRange("field", 0, 10)); @@ -540,7 +540,7 @@ public void IntegerRange() [Test] public void DoubleRange() { - string queryString = "(field ge 0 and field le 10)"; + string queryString = "field ge 0 and field le 10"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.NumericRange("field", 0d, 10d)); @@ -556,7 +556,7 @@ public void DoubleRange() [Test] public void LongRange() { - string queryString = "(field ge 0 and field le 10)"; + string queryString = "field ge 0 and field le 10"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.NumericRange("field", 0L, 10L)); @@ -576,7 +576,7 @@ public void LongRange() [Test] public void Or() { - string queryString = "_name:value1 OR _name:value2"; + string queryString = "_name:value1 _name:value2"; QueryBuilder builder = new QueryBuilder{DefaultChildrenOccur = Matches.Sometimes}; builder.Setup @@ -619,7 +619,7 @@ public void Or() [Test] public void OptionalOr() { - string queryString = "_name:value1 OR _name:value2"; + string queryString = "( _name:value1 OR _name:value2)"; QueryBuilder builder = new QueryBuilder { DefaultChildrenOccur = Matches.Sometimes }; builder.Or @@ -639,7 +639,7 @@ public void OptionalOr() [Test] public void OrExtension() { - string queryString = "_name:value1 OR _name:value2"; + string queryString = "( _name:value1 OR _name:value2)"; QueryBuilder builder = new QueryBuilder(); var builder2 = builder.Or @@ -648,7 +648,6 @@ public void OrExtension() x => x.Term("_name", "value2") ); - Assert.AreEqual(builder2, builder); LucinqQueryModel replacementQuery = builder.Build(); AzureSearchAdapter adapter = new AzureSearchAdapter(); @@ -661,7 +660,7 @@ public void OrExtension() [Test] public void CreateOrExtension() { - string queryString = "_name:value1 OR _name:value2"; + string queryString = "( _name:value1 OR _name:value2)"; QueryBuilder builder = new QueryBuilder(); var group = builder.CreateOrGroup @@ -682,7 +681,7 @@ public void CreateOrExtension() [Test] public void AndExtension() { - string queryString = "+_name:value1 AND +_name:value2"; + string queryString = "( +_name:value1 AND +_name:value2)"; QueryBuilder builder = new QueryBuilder(); var builder2 = builder.And @@ -691,7 +690,6 @@ public void AndExtension() x => x.Term("_name", "value2") ); - Assert.AreEqual(builder2, builder); LucinqQueryModel replacementQuery = builder.Build(); AzureSearchAdapter adapter = new AzureSearchAdapter(); @@ -704,7 +702,7 @@ public void AndExtension() [Test] public void CreateAndExtension() { - string queryString = "+_name:value1 AND +_name:value2"; + string queryString = "( +_name:value1 AND +_name:value2)"; QueryBuilder builder = new QueryBuilder(); var builder2 = builder.CreateAndGroup @@ -726,7 +724,7 @@ public void CreateAndExtension() [Test] public void OptionalAndExtension() { - string queryString = "+_name:value1 AND +_name:value2"; + string queryString = "( +_name:value1 AND +_name:value2)"; QueryBuilder builder = new QueryBuilder(); builder.And @@ -787,7 +785,7 @@ public void TermRangeAndFilter() [Test] public void CompositeTermPhraseWildcardTests() { - string queryString = "+_name:value OR +_name:\"phrase\"~2 OR _name:*wildcard*"; + string queryString = "+_name:value +_name:\"phrase\"~2 _name:*wildcard*"; QueryBuilder builder = new QueryBuilder(); builder.Setup @@ -1006,7 +1004,7 @@ public void NestedOrAnd() [Test] public void NestedEmptyOrAnd() { - string queryString = "( ( +_name:value AND +_name:value))"; + string queryString = "( +_name:value AND +_name:value)"; QueryBuilder builder = new QueryBuilder(); var orGroup1 = builder.Or(); diff --git a/Unit Tests/Lucinq.Solr.UnitTests/App.config b/Unit Tests/Lucinq.Solr.UnitTests/App.config index 36a9972..01a4e5c 100644 --- a/Unit Tests/Lucinq.Solr.UnitTests/App.config +++ b/Unit Tests/Lucinq.Solr.UnitTests/App.config @@ -3,4 +3,4 @@ - + diff --git a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/BaseTestFixture.cs b/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/BaseTestFixture.cs index a6730a3..8785b7a 100644 --- a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/BaseTestFixture.cs +++ b/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/BaseTestFixture.cs @@ -5,175 +5,116 @@ using System.IO; using System.Xml.Linq; using AutoMapper; - using Lucene.Net.Analysis; - using Lucene.Net.Analysis.Standard; - using Lucene.Net.Documents; - using Lucene.Net.Index; - using Lucene.Net.Store; - using Lucene30.Building; using NUnit.Framework; - using Version = Lucene.Net.Util.Version; + using SolrNet.Mapping; [TestFixture] - public abstract class BaseTestFixture - { - protected RAMDirectory IndexDirectory { get; set; } - - /// - /// Simple constructor, only job is to setup the mappings from document to strong type. - /// - protected BaseTestFixture() - { - // Map the lucene document back to our news article. - Mapper.CreateMap() - .ForMember(x => x.Title, opt => opt.MapFrom(y => y.GetValues(BBCFields.Title)[0])) - .ForMember(x => x.Description, opt => opt.MapFrom(y => y.GetValues(BBCFields.Description)[0])) - .ForMember(x => x.PublishDateTime, opt => opt.MapFrom(y => FromTicks(y.GetValues(BBCFields.PublishDateObject)[0]))) - .ForMember(x => x.Link, opt => opt.MapFrom(y => y.GetValues(BBCFields.Link)[0])) - .ForMember(x => x.FileName, opt => opt.MapFrom(y => y.GetValues(BBCFields.FileName)[0])) - .ForMember(x => x.Copyright, opt => opt.Ignore()); - - Mapper.AssertConfigurationIsValid(); - } - - [SetUp] - public void TestFixtureSetup() - { - IndexDirectory = new RAMDirectory(); - BuildInMemoryIndex(IndexDirectory); - } - - [TearDown] - public void TestFixtureTearDown() - { - IndexDirectory.Dispose(); - } - - /// - /// - /// - /// - public void BuildInMemoryIndex(RAMDirectory directory) - { - Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_29); - using (IndexWriter indexWriter = new IndexWriter(directory, analyzer, IndexWriter.MaxFieldLength.UNLIMITED)) - { - string[] rssFiles = System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "\\" + GeneralConstants.Paths.RSSFeed); - int count = 0; - foreach (var rssFile in rssFiles) - { - string secondarySort = count % 2 == 0 ? "A" : "B"; - count++; - var newsArticles = ReadFeed(rssFile); - newsArticles.ForEach( - newsArticle => - indexWriter.AddDocument - ( - x => x.AddAnalysedField(BBCFields.Title, newsArticle.Title, true), - x => x.AddAnalysedField(BBCFields.Description, newsArticle.Description, true), - x => x.AddAnalysedField(BBCFields.Copyright, newsArticle.Copyright), - x => x.AddStoredField(BBCFields.Link, newsArticle.Link), - x => x.AddNonAnalysedField(BBCFields.PublishDateString, TestHelpers.GetDateString(newsArticle.PublishDateTime), true), - x => x.AddNonAnalysedField(BBCFields.PublishDateObject, newsArticle.PublishDateTime, true), - x => x.AddNonAnalysedField(BBCFields.Sortable, newsArticle.Title, true), // must be non-analysed to sort against it - x => x.AddNonAnalysedField(BBCFields.SecondarySort, secondarySort, true), - x => x.AddStoredField(BBCFields.FileName, rssFile)) - - ); - } - - indexWriter.Optimize(); - indexWriter.Dispose(); - } - } - - protected List ReadFeed(string filePath) - { - List newsArticles = new List(); - using (var fileStream = File.OpenText(filePath)) - { - var element = XElement.Load(fileStream); - var channel = element.Element("channel"); - if (channel == null) - { - return null; - } - foreach (var node in channel.Elements("item")) - { - NewsArticle newsArticle = new NewsArticle(); - XElement descriptionElement = node.Element("description"); - if (descriptionElement != null) - { - newsArticle.Description = descriptionElement.Value.Trim(); - } - var titleElement = node.Element("title"); - if (titleElement != null) - { - newsArticle.Title = titleElement.Value; - } - - var linkElement = node.Element("link"); - if (linkElement != null) - { - newsArticle.Link = linkElement.Value; - } - - var publishDateElement = node.Element("pubDate"); - if (publishDateElement != null) - { - newsArticle.PublishDateTime = DateTime.Parse(publishDateElement.Value); - } - newsArticles.Add(newsArticle); - } - } - return newsArticles; - } - - #region helper methods - - /// - /// Helper to convert back from the value in the index to a DateTime - /// - /// - /// - protected DateTime FromTicks(String ticks) - { - long temp; - - if (!Int64.TryParse(ticks, out temp)) - { - return DateTime.MinValue; - } - - return new DateTime(temp); - } - - /// - /// Dump the list of news articles to the error console - /// - /// - protected void WriteDocuments(IList documents) - { - int counter = 0; - Console.Error.WriteLine("Showing the first 30 docs"); - documents.Each( - document => - { - if (counter >= 29) - { - return; - } - - Console.Error.WriteLine("Title: " + document.Title); - Console.Error.WriteLine("Description: " + document.Description); - Console.Error.WriteLine("Publish Date: " + document.PublishDateTime.ToShortDateString()); - Console.Error.WriteLine("Url: " + document.Link); - Console.Error.WriteLine(); - counter++; - } - ); - } - - #endregion - } + public abstract class BaseTestFixture + { + /// + /// Simple constructor, only job is to setup the mappings from document to strong type. + /// + protected BaseTestFixture() + { + } + + [SetUp] + public void TestFixtureSetup() + { + } + + [TearDown] + public void TestFixtureTearDown() + { } + + /// + protected List ReadFeed(string filePath) + { + List newsArticles = new List(); + using (var fileStream = File.OpenText(filePath)) + { + var element = XElement.Load(fileStream); + var channel = element.Element("channel"); + if (channel == null) + { + return null; + } + foreach (var node in channel.Elements("item")) + { + IndexRebuilder.NewsArticle newsArticle = new IndexRebuilder.NewsArticle(); + XElement descriptionElement = node.Element("description"); + if (descriptionElement != null) + { + newsArticle.Description = descriptionElement.Value.Trim(); + } + var titleElement = node.Element("title"); + if (titleElement != null) + { + newsArticle.Title = titleElement.Value; + } + + var linkElement = node.Element("link"); + if (linkElement != null) + { + newsArticle.Link = linkElement.Value; + } + + var publishDateElement = node.Element("pubDate"); + if (publishDateElement != null) + { + newsArticle.PublishDateTime = DateTime.Parse(publishDateElement.Value); + } + newsArticles.Add(newsArticle); + } + } + return newsArticles; + } + + #region helper methods + + /// + /// Helper to convert back from the value in the index to a DateTime + /// + /// + /// + protected DateTime FromTicks(String ticks) + { + long temp; + + if (!Int64.TryParse(ticks, out temp)) + { + return DateTime.MinValue; + } + + return new DateTime(temp); + } + + /// + /// Dump the list of news articles to the error console + /// + /// + protected void WriteDocuments(IList documents) + { + int counter = 0; + Console.Error.WriteLine("Showing the first 30 docs"); + documents.Each( + document => + { + if (counter >= 29) + { + return; + } + + Console.Error.WriteLine("Title: " + document.Title); + Console.Error.WriteLine("Description: " + document.Description); + Console.Error.WriteLine("Publish Date: " + document.PublishDateTime.ToShortDateString()); + Console.Error.WriteLine("Url: " + document.Link); + Console.Error.WriteLine(); + counter++; + } + ); + } + + #endregion + } } diff --git a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/BasicCollectorTests.cs b/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/BasicCollectorTests.cs deleted file mode 100644 index b5012c6..0000000 --- a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/BasicCollectorTests.cs +++ /dev/null @@ -1,98 +0,0 @@ -namespace Lucinq.Solr.UnitTests.IntegrationTests -{ - using System; - using Core.Interfaces; - using Core.Querying; - using Lucene30.Querying; - using NUnit.Framework; - - /// - /// - /// - [TestFixture] - public class BasicCollectorTests : BaseTestFixture - { - /// - /// - /// - [Test] - public void CollectDailyCount() - { - LuceneSearch luceneSearch = new LuceneSearch(IndexDirectory); - - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup - ( - x => x.WildCard(BBCFields.PublishDateString, "*") - ); - - DateCollector collector = new DateCollector(); - luceneSearch.Collect(queryBuilder.Build(), collector); - - Assert.Greater(collector.DailyCount.Keys.Count, 0); - foreach (String day in collector.DailyCount.Keys) - { - Console.Error.WriteLine("Day: {0} had {1} documents", day, collector.DailyCount[day]); - } - - Console.WriteLine(); - } - - // todo: NM - Fix Filter - /* - - /// - /// - /// - [Test] - public void CollectDailyWithFilterCount() - { - LuceneSearch luceneSearch = new LuceneSearch(IndexDirectory); - - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup - ( - x => x.WildCard(BBCFields.Description, "food"), - x => x.Filter(DateRangeFilter.Filter(BBCFields.PublishDateObject, DateTime.Parse("01/02/2013"), DateTime.Parse("28/02/2013"))) - ); - - DateCollector collector = new DateCollector(); - luceneSearch.Collect(queryBuilder.Build(), collector); - - Assert.Greater(collector.DailyCount.Keys.Count, 0); - foreach (String day in collector.DailyCount.Keys) - { - Console.Error.WriteLine("Day: {0} had {1} documents", day, collector.DailyCount[day]); - } - - Console.WriteLine(); - } - */ - - /// - /// - /// - [Test] - public void CollectDailyCountFromQueryBuilder() - { - LuceneSearch luceneSearch = new LuceneSearch(IndexDirectory); - - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup - ( - x => x.WildCard(BBCFields.PublishDateString, "*") - ); - - DateCollector collector = new DateCollector(); - luceneSearch.Collect(queryBuilder, collector); - - Assert.Greater(collector.DailyCount.Keys.Count, 0); - foreach (String day in collector.DailyCount.Keys) - { - Console.Error.WriteLine("Day: {0} had {1} documents", day, collector.DailyCount[day]); - } - - Console.WriteLine(); - } - } -} diff --git a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/BasicTests..cs b/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/BasicTests..cs index f4becd8..a975c79 100644 --- a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/BasicTests..cs +++ b/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/BasicTests..cs @@ -1,24 +1,30 @@ namespace Lucinq.Solr.UnitTests.IntegrationTests { using System; + using System.Collections; using System.Collections.Generic; using System.Linq; using Core.Enums; using Core.Interfaces; using Core.Querying; - using Lucene.Net.Documents; - using Lucene30.Adapters; - using Lucene30.Querying; using NUnit.Framework; + using Querying; + using SolrNet; + [TestFixture] public class BasicTests : BaseTestFixture { - #region [ Properties ] + private const string searchServiceName = "https://solr840:8987/solr"; + private const string indexName = "bbc_index"; + + + #region [ Properties ] [OneTimeSetUp] public void Setup() { + Startup.Init>("https://solr840:8987/solr/bbc_index"); } #endregion @@ -26,458 +32,466 @@ public void Setup() [Test] public void Term() { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); IQueryBuilder queryBuilder = new QueryBuilder(); queryBuilder.Term(BBCFields.Title, "africa"); - var results = ExecuteAndAssert(luceneSearch, queryBuilder, 8); + var results = ExecuteAndAssert(solrSearch, queryBuilder, 7); - Assert.AreEqual(8, results.TotalHits); + Assert.AreEqual(7, results.TotalHits); } + [Test] - [Ignore("Conceptual test for proving index closure")] - public void IndexUsed() - { - LuceneSearch luceneSearch = new LuceneSearch(GeneralConstants.Paths.CarDataIndex); + public void DateRange() + { + + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Term(CarDataFields.Make, "ford"); + DateTime startDate = new DateTime(2012, 12, 1); + DateTime endDate = new DateTime(2013, 1, 1); - var searchResult = luceneSearch.Execute(queryBuilder); + queryBuilder.TermRange("publish_date_time", TestHelpers.GetDateString(startDate), TestHelpers.GetDateString(endDate)); - Assert.AreEqual(8, searchResult.TotalHits); - } + ExecuteAndAssert(solrSearch, queryBuilder, 60); + } - [Test] - public void TermRange() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); + private ISolrSearchResult ExecuteAndAssert(SolrSearch solrSearch, IQueryBuilder queryBuilder, int numberOfHitsExpected) + { - DateTime startDate = new DateTime(2012, 12, 1); - DateTime endDate = new DateTime(2013, 1, 1); + ISolrSearchResult result = solrSearch.Execute(queryBuilder); - queryBuilder.TermRange(BBCFields.PublishDateString, TestHelpers.GetDateString(startDate), TestHelpers.GetDateString(endDate)); + IList> documents = result.GetTopItems(); - ExecuteAndAssert(luceneSearch, queryBuilder, 60); + Console.WriteLine("Searched documents in {0} ms", result.ElapsedTimeMs); + Console.WriteLine(); - } + WriteDocuments(documents); - [Test] - public void SetupSyntax() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup(x => x.Term(BBCFields.Title, "africa")); + Assert.AreEqual(numberOfHitsExpected, result.TotalHits); - ExecuteAndAssert(luceneSearch, queryBuilder, 8); - } + return result; + } - [Test] - public void SimpleOrClauseSuccessful() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); + [Test] + public void SetupSyntax() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Setup(x => x.Term(BBCFields.Title, "africa")); - queryBuilder.Or - ( - x => x.Term(BBCFields.Title, "africa"), - x => x.Term(BBCFields.Title, "europe") - ); + ExecuteAndAssert(solrSearch, queryBuilder, 7); + } - ExecuteAndAssert(luceneSearch, queryBuilder, 12); - } - [Test] - public void SimpleAndClauseSuccessful() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.And - ( - x => x.Term(BBCFields.Title, "africa"), - x => x.Term(BBCFields.Title, "road") - ); - ExecuteAndAssert(luceneSearch, queryBuilder, 1); - } + private void WriteDocuments(ICollection> documents) + { + int counter = 0; + Console.WriteLine("Showing the first 30 docs"); + + foreach (var document in documents) + { + if (counter >= 29) + { + return; + } + + Console.WriteLine("Title: " + document["title"]); + Console.WriteLine("Description: " + document["description"]); + Console.WriteLine("Publish Date: " + document["publish_date_time"]); + Console.WriteLine("Url: " + document["link"]); + Console.WriteLine(); + counter++; + } + } - [Test] - public void RemoveAndReexecute() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Term(BBCFields.Title, "africa", key: "africacriteria"); + [Test] + public void SimpleOrClauseSuccessful() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); - var results = ExecuteAndAssert(luceneSearch, queryBuilder, 8); + queryBuilder.Or + ( + x => x.Term(BBCFields.Title, "africa"), + x => x.Term(BBCFields.Title, "europe") + ); - queryBuilder.Queries.Remove("africacriteria"); - queryBuilder.Term(BBCFields.Title, "report", key: "businesscriteria"); + ExecuteAndAssert(solrSearch, queryBuilder, 10); + } - Console.WriteLine("\r\nSecond Criteria"); + [Test] + public void SimpleAndClauseSuccessful() + { - var results2 = ExecuteAndAssert(luceneSearch, queryBuilder, 5); + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); - Assert.AreNotEqual(results.TotalHits, results2.TotalHits); - } + queryBuilder.And + ( + x => x.Term(BBCFields.Title, "africa"), + x => x.Term(BBCFields.Title, "road") + ); + + ExecuteAndAssert(solrSearch, queryBuilder, 1); + } - [Test] - public void TermsOr() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Terms(BBCFields.Title, new[] {"europe", "africa"}, Matches.Sometimes); - ExecuteAndAssert(luceneSearch, queryBuilder, 12); - } + + [Test] + public void RemoveAndReexecute() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + + queryBuilder.Term(BBCFields.Title, "africa", key: "africacriteria"); + + var results = ExecuteAndAssert(solrSearch, queryBuilder, 7); + + queryBuilder.Queries.Remove("africacriteria"); + queryBuilder.Term(BBCFields.Title, "report", key: "businesscriteria"); + + Console.WriteLine("\r\nSecond Criteria"); + + var results2 = ExecuteAndAssert(solrSearch, queryBuilder, 5); + + Assert.AreNotEqual(results.TotalHits, results2.TotalHits); + } + + [Test] + public void TermsOr() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Terms(BBCFields.Title, new[] { "europe", "africa" }, Matches.Sometimes); + ExecuteAndAssert(solrSearch, queryBuilder, 10); + } [Test] public void EasyOr() { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); IQueryBuilder queryBuilder = new QueryBuilder(); queryBuilder.Or( x => x.Term(BBCFields.Title, "europe"), x => x.Term(BBCFields.Title, "africa")); - ExecuteAndAssert(luceneSearch, queryBuilder, 12); - } - - /*[Test] - public void SimpleNot() - { - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Not().Term("_name", "home"); - var results = ExecuteAndAssert(queryBuilder, 12); - }*/ + ExecuteAndAssert(solrSearch, queryBuilder, 10); + } - [Test] - public void PhraseDistance() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); + [Test] + public void PhraseDistance() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); queryBuilder.Phrase(2, new[] - { - new KeyValuePair(BBCFields.Title, "wildlife"), - new KeyValuePair(BBCFields.Title, "africa") - }); + { + new KeyValuePair(BBCFields.Title, "wildlife"), + new KeyValuePair(BBCFields.Title, "africa") + }); - ExecuteAndAssert(luceneSearch, queryBuilder, 1); - } + ExecuteAndAssert(solrSearch, queryBuilder, 1); + } - [Test] - public void Fuzzy() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Fuzzy(BBCFields.Title, "afric", 0.5f); - ExecuteAndAssert(luceneSearch, queryBuilder, 16); - } + [Test] + public void Fuzzy() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Fuzzy(BBCFields.Title, "afric", 0.5f); + ExecuteAndAssert(solrSearch, queryBuilder, 16); + } - [Test] - public void Paging() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory,false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup(x => x.WildCard(BBCFields.Description, "a*")); - var results = ExecuteAndAssertPaged(luceneSearch, queryBuilder, 902, 0, 10); + [Test] + public void Paging() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Setup(x => x.WildCard(BBCFields.Description, "a*")); + + var results = ExecuteAndAssertPaged(solrSearch, queryBuilder, 1318, 0, 10); var documents = results.GetRange(0, 9); - Assert.AreEqual(10, documents.Count); + Assert.AreEqual(10, documents.Count); - var results2 = ExecuteAndAssertPaged(luceneSearch, queryBuilder, 902, 1, 11); - var documents2 = results2.GetRange(1, 10); - Assert.AreEqual(10, documents2.Count); + var results2 = ExecuteAndAssertPaged(solrSearch, queryBuilder, 1318, 1, 11); + var documents2 = results2.GetRange(1, 10); + Assert.AreEqual(10, documents2.Count); - for (var i = 0; i < documents.Count - 1; i++) - { - Assert.AreEqual(documents2[i].GetValues(BBCFields.Title).FirstOrDefault(), documents[i+1].GetValues(BBCFields.Title).FirstOrDefault()); - } - - } + for (var i = 0; i < documents.Count - 1; i++) + { + Assert.AreEqual(documents2[i][BBCFields.Title], documents[i + 1][BBCFields.Title]); + } - [Test] - public void Sorting() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup - ( - x => x.WildCard(BBCFields.Description, "a*"), - x => x.Sort(BBCFields.Sortable) - ); - - ILuceneSearchResult result = ExecuteAndAssert(luceneSearch, queryBuilder, 902); - IList documents = result.GetRange(0, 100); - for (var i = 1; i < documents.Count; i++) - { - string thisDocumentSortable = documents[i].GetValues(BBCFields.Sortable).FirstOrDefault(); - string lastDocumentSortable = documents[i - 1].GetValues(BBCFields.Sortable).FirstOrDefault(); - Assert.IsTrue(String.Compare(thisDocumentSortable, lastDocumentSortable, StringComparison.Ordinal) >= 0); - } - } + } - [Test] - public void MultipleSorting() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup - ( - x => x.WildCard(BBCFields.Description, "a*"), - x => x.Sort(BBCFields.SecondarySort), - x => x.Sort(BBCFields.Sortable) - ); - - ILuceneSearchResult result = ExecuteAndAssert(luceneSearch, queryBuilder, 902); - IList documents = result.GetRange(0, 1000); - for (var i = 1; i < documents.Count; i++) - { - string thisDocumentSortable = GetSecondarySortString(documents[i]); - string lastDocumentSortable = GetSecondarySortString(documents[i - 1]); - Assert.IsTrue(String.Compare(thisDocumentSortable, lastDocumentSortable, StringComparison.Ordinal) >= 0); - } - } + [Test] + public void Sorting() + { - [Test] - public void MultipleSortingDescending() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup - ( - x => x.WildCard(BBCFields.Description, "a*"), - x => x.Sort(BBCFields.SecondarySort, true), - x => x.Sort(BBCFields.Sortable, true) - ); - - ILuceneSearchResult result = ExecuteAndAssert(luceneSearch, queryBuilder, 902); - IList documents = result.GetRange(0, 1000); - for (var i = 1; i < documents.Count; i++) - { - string thisDocumentSortable = GetSecondarySortString(documents[i]); - string lastDocumentSortable = GetSecondarySortString(documents[i - 1]); - Assert.IsTrue(String.Compare(lastDocumentSortable, thisDocumentSortable, StringComparison.Ordinal) >= 0); - } - } + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Setup + ( + x => x.WildCard(BBCFields.Description, "a*"), + x => x.Sort("title_sort") + ); + + ISolrSearchResult result = ExecuteAndAssert(solrSearch, queryBuilder, 1318); + var documents = result.GetRange(0, 100); + for (var i = 1; i < documents.Count; i++) + { + string thisDocumentSortable = documents[i][BBCFields.Title].ToString(); + string lastDocumentSortable = documents[i - 1][BBCFields.Title].ToString(); + Assert.IsTrue(String.Compare(thisDocumentSortable, lastDocumentSortable, StringComparison.Ordinal) >= 0); + } + } - private string GetSecondarySortString(Document document) - { - return String.Format("{0}_{1}", document.GetValues(BBCFields.SecondarySort).FirstOrDefault(), document.GetValues(BBCFields.Sortable).FirstOrDefault()); - } - [Test] - public void SortDescending() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup - ( - x => x.WildCard(BBCFields.Description, "a*"), - x => x.Sort(BBCFields.Sortable, true) - ); - - ILuceneSearchResult result = ExecuteAndAssert(luceneSearch, queryBuilder, 902); - IList documents = result.GetRange(0, 10); - for (var i = 1; i < documents.Count; i++) - { - string thisDocumentSortable = documents[i].GetValues(BBCFields.Sortable).FirstOrDefault(); - string lastDocumentSortable = documents[i - 1].GetValues(BBCFields.Sortable).FirstOrDefault(); - Assert.IsTrue(String.Compare(thisDocumentSortable, lastDocumentSortable, StringComparison.Ordinal) <= 0); - } - } + [Test] + public void MultipleSorting() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Setup + ( + x => x.WildCard(BBCFields.Description, "a*"), + x => x.Sort("title_sort"), + x => x.Sort("secondary_sort") + ); + + ISolrSearchResult result = ExecuteAndAssert(solrSearch, queryBuilder, 1318); + var documents = result.GetRange(0, 1000); + for (var i = 1; i < documents.Count; i++) + { + string thisDocumentSortable = GetSecondarySortString(documents[i]); + string lastDocumentSortable = GetSecondarySortString(documents[i - 1]); + Assert.IsTrue(String.Compare(thisDocumentSortable, lastDocumentSortable, StringComparison.Ordinal) >= 0); + } + } + + + private ISolrSearchResult ExecuteAndAssertPaged(SolrSearch solrSearch, IQueryBuilder queryBuilder, int numberOfHitsExpected, int start, int end) + { + // Search = new SolrSearch(GeneralConstants.Paths.BBCIndex); + var result = solrSearch.Execute(queryBuilder); + var documents = result.GetRange(start, end); + + Console.WriteLine("Searched documents in {0} ms", result.ElapsedTimeMs); + Console.WriteLine(); + + WriteDocuments(documents); + + Assert.AreEqual(numberOfHitsExpected, result.TotalHits); + + return result; + } + + private string GetSecondarySortString(Dictionary document) + { + return String.Format("{0}_{1}", document["secondary_sort"].ToString(), document["title_sort"].ToString()); + } - [Test] - public void TermsAnd() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Terms(BBCFields.Title, new[] { "africa", "road" }, Matches.Always); - ExecuteAndAssert(luceneSearch, queryBuilder, 1); - } + + [Test] + public void TermsAnd() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Terms(BBCFields.Title, new[] { "africa", "road" }, Matches.Always); + ExecuteAndAssert(solrSearch, queryBuilder, 1); + } [Test] public void EasyAnd() { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); IQueryBuilder queryBuilder = new QueryBuilder(); queryBuilder.And( x => x.Term(BBCFields.Title, "road"), x => x.Term(BBCFields.Title, "africa")); - ExecuteAndAssert(luceneSearch, queryBuilder, 1); + ExecuteAndAssert(solrSearch, queryBuilder, 1); } - [Test] - public void WildCard() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup(x => x.WildCard(BBCFields.Description, "a*")); + [Test] + public void WildCard() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Setup(x => x.WildCard(BBCFields.Description, "a*")); - ExecuteAndAssert(luceneSearch, queryBuilder, 902); - } + ExecuteAndAssert(solrSearch, queryBuilder, 1318); + } - [Test] - public void ChainedTerms() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup - ( - x => x.WildCard(BBCFields.Description, "a*"), - x => x.Term(BBCFields.Description, "police") - ); + [Test] + public void ChainedTerms() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Setup + ( + x => x.WildCard(BBCFields.Description, "a*"), + x => x.Term(BBCFields.Description, "police") + ); - ExecuteAndAssert(luceneSearch, queryBuilder, 17); - } + ExecuteAndAssert(solrSearch, queryBuilder, 25); + } - [Test] - public void Group() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup - ( - x => x.WildCard(BBCFields.Title, "africa"), - x => x.Group().Setup - ( - y => y.Term(BBCFields.Description, "africa", Matches.Sometimes), - y => y.Term(BBCFields.Description, "amazing", Matches.Sometimes) - ) - ); - - ExecuteAndAssert(luceneSearch, queryBuilder, 5); - } + [Test] + public void Group() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Setup + ( + x => x.WildCard(BBCFields.Title, "africa"), + x => x.Group().Setup + ( + y => y.Term(BBCFields.Description, "africa", Matches.Sometimes), + y => y.Term(BBCFields.Description, "amazing", Matches.Sometimes) + ) + ); + + ExecuteAndAssert(solrSearch, queryBuilder, 5); + } - [Test] - public void SpeedExample() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); - Console.WriteLine("A simple test to show Lucene getting quicker as queries are done"); - Console.WriteLine("----------------------------------------------------------------"); - Console.WriteLine(); - Console.WriteLine("Pass 1"); - SpeedExampleExecute(luceneSearch, "b"); - Console.WriteLine(); - - Console.WriteLine("Pass 2"); - SpeedExampleExecute(luceneSearch, "c"); - Console.WriteLine(); - - Console.WriteLine("Pass 3"); - SpeedExampleExecute(luceneSearch, "a"); - - Console.WriteLine(); - Console.WriteLine("** Repeating Passes **"); - - Console.WriteLine("Repeat Pass 1"); - SpeedExampleExecute(luceneSearch, "b"); - Console.WriteLine(); - - Console.WriteLine("Repeat Pass 2"); - SpeedExampleExecute(luceneSearch, "c"); - Console.WriteLine(); - - Console.WriteLine("Repeat Pass 3"); - SpeedExampleExecute(luceneSearch, "a"); - } - [Test] + [Test] + public void SpeedExample() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + Console.WriteLine("A simple test to show Lucene getting quicker as queries are done"); + Console.WriteLine("----------------------------------------------------------------"); + Console.WriteLine(); + Console.WriteLine("Pass 1"); + SpeedExampleExecute(solrSearch, "b"); + Console.WriteLine(); + + Console.WriteLine("Pass 2"); + SpeedExampleExecute(solrSearch, "c"); + Console.WriteLine(); + + Console.WriteLine("Pass 3"); + SpeedExampleExecute(solrSearch, "a"); + + Console.WriteLine(); + Console.WriteLine("** Repeating Passes **"); + + Console.WriteLine("Repeat Pass 1"); + SpeedExampleExecute(solrSearch, "b"); + Console.WriteLine(); + + Console.WriteLine("Repeat Pass 2"); + SpeedExampleExecute(solrSearch, "c"); + Console.WriteLine(); + + Console.WriteLine("Repeat Pass 3"); + SpeedExampleExecute(solrSearch, "a"); + } + + [Test] public void Enumerable() { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); IQueryBuilder queryBuilder = new QueryBuilder(); queryBuilder.Term(BBCFields.Title, "africa"); - var result = luceneSearch.Execute(queryBuilder); - WriteDocuments(result); - Assert.AreEqual(8, result.Count()); - } + var result = solrSearch.Execute(queryBuilder); + /*WriteDocuments(result);*/ + Assert.AreEqual(7, result.Count()); + } [Test] public void EnumerableWithWhere() { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false), new LuceneAdapter()); + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); IQueryBuilder queryBuilder = new QueryBuilder(); queryBuilder.Term(BBCFields.Title, "africa"); - var result = luceneSearch.Execute(queryBuilder).Where(doc => doc.GetField(BBCFields.Title).StringValue.IndexOf("your", StringComparison.OrdinalIgnoreCase) >= 0).ToArray(); + var result = solrSearch.Execute(queryBuilder).Where(doc => doc[BBCFields.Title].ToString().IndexOf("your", StringComparison.OrdinalIgnoreCase) >= 0).ToArray(); WriteDocuments(result); Assert.AreEqual(1, result.Count()); } + public void SpeedExampleExecute(SolrSearch solrSearch, string startingCharacter) + { + // Chosen due to it being the slowest query - public void SpeedExampleExecute(LuceneSearch luceneSearch, string startingCharacter) - { - // Chosen due to it being the slowest query - - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Setup - ( - x => x.WildCard(BBCFields.Description, startingCharacter + "*"), - x => x.Term(BBCFields.Description, "sport") - ); - var result = luceneSearch.Execute(queryBuilder); - - Console.WriteLine("Total Results: {0}", result.TotalHits); - Console.WriteLine("Elapsed Time: {0}", result.ElapsedTimeMs); - } - - private ILuceneSearchResult ExecuteAndAssert(LuceneSearch luceneSearch, IQueryBuilder queryBuilder, int numberOfHitsExpected) - { - var result = luceneSearch.Execute(queryBuilder); - - var documents = result.GetTopItems(); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Setup + ( + x => x.WildCard(BBCFields.Description, startingCharacter + "*"), + x => x.Term(BBCFields.Description, "sport") + ); + var result = solrSearch.Execute(queryBuilder); + + Console.WriteLine("Total Results: {0}", result.TotalHits); + Console.WriteLine("Elapsed Time: {0}", result.ElapsedTimeMs); + } + [Test] + public void Filter() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); - Console.WriteLine("Searched documents in {0} ms", result.ElapsedTimeMs); - Console.WriteLine(); + queryBuilder.Term(BBCFields.Title, "Africa"); + queryBuilder.Filter(new LucinqFilter("description", "Close encounters from the heart of Africa", Comparator.Equals)); - WriteDocuments(documents); + var results = ExecuteAndAssert(solrSearch, queryBuilder, 1); - Assert.AreEqual(numberOfHitsExpected, result.TotalHits); - - return result; - } + Assert.AreEqual(1, results.TotalHits); + } - private ILuceneSearchResult ExecuteAndAssertPaged(LuceneSearch luceneSearch, IQueryBuilder queryBuilder, int numberOfHitsExpected, int start, int end) - { - // Search = new LuceneSearch(GeneralConstants.Paths.BBCIndex); - var result = luceneSearch.Execute(queryBuilder); - IList documents = result.GetRange(start, end); - Console.WriteLine("Searched documents in {0} ms", result.ElapsedTimeMs); - Console.WriteLine(); - - WriteDocuments(documents); + [Test] + public void MultipleSortingDescending() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Setup + ( + x => x.WildCard(BBCFields.Description, "a*"), + x => x.Sort(BBCFields.SecondarySort, true), + x => x.Sort("title_sort", true) + ); + + ISolrSearchResult result = ExecuteAndAssert(solrSearch, queryBuilder, 1318); + var documents = result.GetRange(0, 1000); + for (var i = 1; i < documents.Count; i++) + { + string thisDocumentSortable = GetSecondarySortString(documents[i]); + string lastDocumentSortable = GetSecondarySortString(documents[i - 1]); + Assert.IsTrue(String.Compare(lastDocumentSortable, thisDocumentSortable, StringComparison.Ordinal) >= 0); + } + } - Assert.AreEqual(numberOfHitsExpected, result.TotalHits); - return result; - } - private void WriteDocuments(IEnumerable documents) - { - int counter = 0; - Console.WriteLine("Showing the first 30 docs"); - foreach (var document in documents) - { - if (counter >= 29) - { - return; - } - Console.WriteLine("Title: " + document.GetValues(BBCFields.Title)[0]); - Console.WriteLine("Secondary Sort:" + document.GetValues(BBCFields.SecondarySort)[0]); - Console.WriteLine("Description: " + document.GetValues(BBCFields.Description)[0]); - Console.WriteLine("Publish Date: " + document.GetValues(BBCFields.PublishDateString)[0]); - Console.WriteLine("Url: "+ document.GetValues(BBCFields.Link)[0]); - Console.WriteLine(); - counter++; - } - } - } + [Test] + public void SortDescending() + { + SolrSearch solrSearch = new SolrSearch(new SolrSearchDetails(searchServiceName), indexName); + IQueryBuilder queryBuilder = new QueryBuilder(); + queryBuilder.Setup + ( + x => x.WildCard(BBCFields.Description, "a*"), + x => x.Sort("title_sort", true) + ); + + ISolrSearchResult result = ExecuteAndAssert(solrSearch, queryBuilder, 1318); + var documents = result.GetRange(0, 10); + for (var i = 1; i < documents.Count; i++) + { + string thisDocumentSortable = documents[i]["title_sort"].ToString(); + string lastDocumentSortable = documents[i - 1]["title_sort"].ToString(); + Assert.IsTrue(String.Compare(thisDocumentSortable, lastDocumentSortable, StringComparison.Ordinal) <= 0); + } + } + } } diff --git a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/DateFieldTests.cs b/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/DateFieldTests.cs deleted file mode 100644 index 9e9fa82..0000000 --- a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/DateFieldTests.cs +++ /dev/null @@ -1,100 +0,0 @@ -namespace Lucinq.Solr.UnitTests.IntegrationTests -{ - using System; - using System.Collections.Generic; - using AutoMapper; - using Core.Interfaces; - using Core.Querying; - using Lucene.Net.Documents; - using Lucene30.Querying; - using NUnit.Framework; - - [TestFixture] - public class DateFieldTests : BaseTestFixture - { - /// - /// Pull out all the articles within a particular date range and dump them to the error console. - /// - [Test] - public void GetArticlesWithDateTest() - { - LuceneSearch luceneSearch = new LuceneSearch(IndexDirectory); - - - IQueryBuilder queryBuilder = new QueryBuilder(); - DateTime february = DateTime.Parse("01/02/2013"); - - queryBuilder.Setup( - x => x.DateRange(BBCFields.PublishDateObject, february, february.AddDays(28)) - ); - - ILuceneSearchResult result = luceneSearch.Execute(queryBuilder); - IList data = Mapper.Map, IList>(result.GetTopItems()); - - WriteDocuments(data); - - Console.WriteLine("Searched {0} documents in {1} ms", result.TotalHits, result.ElapsedTimeMs); - Console.WriteLine(); - - Assert.AreNotEqual(0, result.TotalHits); - } - - // todo: NM - fix filter - /* - /// - /// Pull out all the articles within a particular date range and dump them to the error console. - /// - [Test] - public void SearchArticlesWithDateFilterTest() - { - LuceneSearch luceneSearch = new LuceneSearch(IndexDirectory); - - IQueryBuilder queryBuilder = new QueryBuilder(); - DateTime february = DateTime.Parse("01/02/2013"); - DateTime end = DateTime.Parse("28/02/2013"); - - queryBuilder.Setup( - x => x.WildCard(BBCFields.Description, "food", Matches.Always), - x => x.Filter(DateRangeFilter.Filter(BBCFields.PublishDateObject, february, end)) - ); - - ILuceneSearchResult result = luceneSearch.Execute(queryBuilder); - IList data = Mapper.Map, IList>(result.GetTopItems()); - - WriteDocuments(data); - - Console.WriteLine("Searched {0} documents in {1} ms", result.TotalHits, result.ElapsedTimeMs); - Console.WriteLine(); - - Assert.AreNotEqual(0, result.TotalHits); - } - */ - - /// - /// Search all the articles within a particular date range and dump them to the error console. - /// - [Test] - public void SearchArticlesWithinDateRangeTest() - { - LuceneSearch luceneSearch = new LuceneSearch(IndexDirectory); - - IQueryBuilder queryBuilder = new QueryBuilder(); - DateTime month = DateTime.Parse("01/02/2013"); - - queryBuilder.Setup( - x => x.DateRange(BBCFields.PublishDateObject, month, month.AddDays(28)), - x => x.WildCard(BBCFields.Description, "food") - ); - - ILuceneSearchResult result = luceneSearch.Execute(queryBuilder); - IList data = Mapper.Map, IList>(result.GetTopItems()); - - WriteDocuments(data); - - Console.WriteLine("Searched {0} documents in {1} ms", result.TotalHits, result.ElapsedTimeMs); - Console.WriteLine(); - - Assert.AreNotEqual(0, result.TotalHits); - } - } -} \ No newline at end of file diff --git a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/FilesystemDirectoryTests.cs b/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/FilesystemDirectoryTests.cs deleted file mode 100644 index 24f5e82..0000000 --- a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/FilesystemDirectoryTests.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace Lucinq.Solr.UnitTests.IntegrationTests -{ - using Core.Querying; - using Lucene.Net.Store; - using Lucene30.Querying; - using NUnit.Framework; - - [TestFixture] - public class FilesystemDirectoryTests - { - [Test] - public void OpenAndSearchOnFileSystemUsingPath() - { - LuceneSearch search = new LuceneSearch(GeneralConstants.Paths.CarDataIndex); - QueryBuilder builder = new QueryBuilder(x => x.Term(CarDataFields.Make, "ford")); - var result = search.Execute(builder); - Assert.Greater(result.TotalHits, 0); - } - - [Test] - public void OpenAndSearchOnFileSystemUsingFSDirectory() - { - using (var directory = FSDirectory.Open(GeneralConstants.Paths.CarDataIndex)) - { - LuceneSearch search = new LuceneSearch(directory); - QueryBuilder builder = new QueryBuilder(x => x.Term(CarDataFields.Make, "ford")); - var result = search.Execute(builder); - Assert.Greater(result.TotalHits, 0); - } - } - } -} diff --git a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/IndexRebuilder.cs b/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/IndexRebuilder.cs index c89fc04..20aea46 100644 --- a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/IndexRebuilder.cs +++ b/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/IndexRebuilder.cs @@ -7,268 +7,190 @@ using System.Globalization; using System.IO; using System.Xml.Linq; - using Lucene.Net.Analysis; - using Lucene.Net.Analysis.Standard; - using Lucene.Net.Index; - using Lucene.Net.Store; - using Lucene30.Building; + using CommonServiceLocator; using NUnit.Framework; + using SolrNet; + using SolrNet.Attributes; + using SolrNet.Impl; using Directory = System.IO.Directory; - using Version = Lucene.Net.Util.Version; [TestFixture] - [Ignore ("Index Rebuilding is specific, run the individual tests.")] - public class IndexRebuilder + /*[Ignore("Index Rebuilding is specific, run the individual tests.")]*/ + public class IndexRebuilder { #region [ BBC News Indexing ] + private const string searchServiceName = "https://solr840:8987/solr"; + private const string indexName = "bbc_index"; + [Test] - public void ReadFeedAndDisplay() - { - var newsArticles = ReadFeed(String.Format("{0}{1}", GeneralConstants.Paths.RSSFeed, @"\Business.xml")); - foreach (var newsArticle in newsArticles) - { - Console.WriteLine(newsArticle.Title); - Console.WriteLine(newsArticle.Description); - Console.WriteLine(newsArticle.Copyright); - Console.WriteLine(newsArticle.Link); - Console.WriteLine(TestHelpers.GetDateString(newsArticle.PublishDateTime)); - Console.WriteLine(); - } - } - - /// - /// Before you say - not robust - just does enough to get the job done ;) - /// - [Ignore("Don't build this under normal unit test conditions")] - [Test] - public void BuildBBCIndex() - { - // IF YOU WANT TO RUN THIS, DELETE THE CONTENTS OF THE EXISTING INDEX FIRST, OTHERWISE, IT WILL APPEND - - if (Directory.Exists(GeneralConstants.Paths.BBCIndex)) - { - Directory.Delete(GeneralConstants.Paths.BBCIndex, true); - } - - var indexFolder = FSDirectory.Open(new DirectoryInfo(GeneralConstants.Paths.BBCIndex)); - - Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_29); - using (IndexWriter indexWriter = new IndexWriter(indexFolder, analyzer, IndexWriter.MaxFieldLength.UNLIMITED)) - { - string[] rssFiles = Directory.GetFiles(GeneralConstants.Paths.RSSFeed); - int count = 0; - foreach (var rssFile in rssFiles) - { - /*if (count > 4) - { - break; - }*/ - string secondarySort = count%2 == 0 ? "A" : "B"; - count ++; - var newsArticles = ReadFeed(rssFile); - newsArticles.ForEach( - newsArticle => - indexWriter.AddDocument - ( - x => x.AddAnalysedField(BBCFields.Title, newsArticle.Title, true), - x => x.AddAnalysedField(BBCFields.Description, newsArticle.Description, true), - x => x.AddAnalysedField(BBCFields.Copyright, newsArticle.Copyright), - x => x.AddStoredField(BBCFields.Link, newsArticle.Link), - x => x.AddNonAnalysedField(BBCFields.PublishDateString, TestHelpers.GetDateString(newsArticle.PublishDateTime), true), - x => x.AddNonAnalysedField(BBCFields.PublishDateObject, newsArticle.PublishDateTime, true), - x => x.AddNonAnalysedField(BBCFields.Sortable, newsArticle.Title, true), // must be non-analysed to sort against it - x => x.AddNonAnalysedField(BBCFields.SecondarySort, secondarySort, true)) - ); - } - - indexWriter.Optimize(); - indexWriter.Dispose(); - } - } - - protected List ReadFeed(string filePath) - { - List newsArticles = new List(); - using (var fileStream = File.OpenText(filePath)) - { - var element = XElement.Load(fileStream); - var channel = element.Element("channel"); - if (channel == null) - { - return null; - } - foreach (var node in channel.Elements("item")) - { - NewsArticle newsArticle = new NewsArticle(); - XElement descriptionElement = node.Element("description"); - if (descriptionElement != null) - { - newsArticle.Description = descriptionElement.Value.Trim(); - } - var titleElement = node.Element("title"); - if (titleElement != null) - { - newsArticle.Title = titleElement.Value; - } - - var linkElement = node.Element("link"); - if (linkElement != null) - { - newsArticle.Link = linkElement.Value; - } - - var publishDateElement = node.Element("pubDate"); - if (publishDateElement != null) - { - newsArticle.PublishDateTime = DateTime.Parse(publishDateElement.Value); - } - newsArticles.Add(newsArticle); - } - } - return newsArticles; + public void ReadFeedAndDisplay() + { + var newsArticles = ReadFeed(String.Format("{0}{1}", GeneralConstants.Paths.RSSFeed, @"\Business.xml")); + foreach (var newsArticle in newsArticles) + { + Console.WriteLine(newsArticle.Title); + Console.WriteLine(newsArticle.Description); + Console.WriteLine(newsArticle.Copyright); + Console.WriteLine(newsArticle.Link); + Console.WriteLine(TestHelpers.GetDateString(newsArticle.PublishDateTime)); + Console.WriteLine(); + } } - #endregion - - [Ignore("Indexing is not part of the normal tests")] + /// + /// Before you say - not robust - just does enough to get the job done ;) + /// + /*[Ignore("Don't build this under normal unit test conditions")]*/ [Test] - public void BuildCarDataIndex() - { - var carDataItems = GetCarDataItems(); + public void BuildBBCIndex() + { + // IF YOU WANT TO RUN THIS, DELETE THE CONTENTS OF THE EXISTING INDEX FIRST, OTHERWISE, IT WILL APPEND + + Startup.Init>("https://solr840:8987/solr/bbc_index"); + + /* + var headerParser = ServiceLocator.Current.GetInstance(); + var statusParser = ServiceLocator.Current.GetInstance(); + ISolrCoreAdmin solrCoreAdmin = + new SolrCoreAdmin(new SolrConnection(searchServiceName), headerParser, statusParser); + solrCoreAdmin.Create(coreName: indexName, instanceDir: indexName);*/ + - if (carDataItems.Count == 0) + string[] rssFiles = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "\\" + GeneralConstants.Paths.RSSFeed); + int count = 0; + List newsArticles = new List(); + foreach (var rssFile in rssFiles) { - Assert.Fail("No Car Data Items Were Found"); + string secondarySort = count % 2 == 0 ? "A" : "B"; + count++; + List feedArticles = ReadFeed(rssFile); + newsArticles.AddRange(feedArticles); + } - if (Directory.Exists(GeneralConstants.Paths.CarDataIndex)) - { - Directory.Delete(GeneralConstants.Paths.CarDataIndex, true); - } - - var indexFolder = FSDirectory.Open(new DirectoryInfo(GeneralConstants.Paths.CarDataIndex)); - - Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30); - using (IndexWriter indexWriter = new IndexWriter(indexFolder, analyzer, IndexWriter.MaxFieldLength.UNLIMITED)) - { - foreach (var originalDataItem in carDataItems) - { - var carDataItem = originalDataItem; - indexWriter.AddDocument( - x => x.AddAnalysedField(CarDataFields.AdvertId, carDataItem.AdvertId.ToString().ToLower()), - x => x.AddNonAnalysedField(CarDataFields.MakeId, carDataItem.MakeId), - x => x.AddNonAnalysedField(CarDataFields.ModelId, carDataItem.ModelId), - x => x.AddNonAnalysedField(CarDataFields.Code, carDataItem.Code), - x => x.AddAnalysedField(CarDataFields.Make, carDataItem.Make), - x => x.AddAnalysedField(CarDataFields.Model, carDataItem.Make), - x => x.AddAnalysedField(CarDataFields.Options, carDataItem.Options), - x => x.AddNonAnalysedField(CarDataFields.AdvertTypeId, carDataItem.AdvertTypeId), - x => x.AddAnalysedField(CarDataFields.AdvertType, carDataItem.AdvertType), - x => x.AddNonAnalysedField(CarDataFields.IsLive, carDataItem.AdvertStatusId > 1 ? "1" : "0"), - x => x.AddNonAnalysedField(CarDataFields.DateCreated, carDataItem.Created), - x => x.AddAnalysedField(CarDataFields.Town, carDataItem.Town), - x => x.AddAnalysedField(CarDataFields.County, carDataItem.County), - x => x.AddAnalysedField(CarDataFields.Postcode, carDataItem.Postcode), - x => x.AddAnalysedField(CarDataFields.FuelType, carDataItem.FuelType), - x => x.AddNonAnalysedField(CarDataFields.Mileage, carDataItem.Mileage.ToString()), - x => x.AddAnalysedField(CarDataFields.Price, carDataItem.Price.ToString(CultureInfo.InvariantCulture), true) - ); - } - } - } - - private static List GetCarDataItems() - { - List carDataItems = new List(); - - using ( - SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["CarData"].ConnectionString) - ) - { - using (SqlCommand command = new SqlCommand("usp_LucinqTestData", connection)) - { - connection.Open(); - SqlDataReader reader = command.ExecuteReader(); - while (reader.Read()) - { - // ignore data with no price - if (reader["Price"] == DBNull.Value) - { - continue; - } - CarDataItem item = new CarDataItem - { - AdvertId = (Guid) reader["AdvertId"], - Created = (DateTime) reader["DateCreated"], - MakeId = (int) reader["MakeId"], - ModelId = (int) reader["ModelId"], - Code = reader["Code"].ToString(), - Make = reader["Make"].ToString(), - Model = reader["Model"].ToString(), - Variant = reader.GetValueOrDefault("Variant"), - Options = reader.GetValueOrDefault("Options"), - FuelType = reader.GetValueOrDefault("FuelType"), - AdvertTypeId = (int) reader["AdvertTypeId"], - AdvertType = reader["AdvertType"].ToString(), - AdvertStatusId = (int) reader["AdvertStatusId"], - AdvertStatus = reader["AdvertStatus"].ToString(), - Town = reader.GetValueOrDefault("Town"), - County = reader.GetValueOrDefault("County"), - Postcode = reader.GetValueOrDefault("Postcode"), - Price = reader.GetValueOrDefault("Price"), - Mileage = reader.GetValueOrDefault("Mileage") - }; - carDataItems.Add(item); - } - } - } - return carDataItems; - } - } + foreach (var newsArticle in newsArticles) + { + newsArticle.Key = count.ToString(); + count++; + } - public class CarDataItem - { - public Guid AdvertId { get; set; } - public DateTime Created { get; set; } - public int MakeId { get; set; } - public int ModelId { get; set; } - public string Code { get; set; } - public string Make { get; set; } - public string Model { get; set; } - public string Variant { get; set; } - public string Options { get; set; } - public int AdvertTypeId { get; set; } - public string AdvertType { get; set; } - public int AdvertStatusId { get; set; } - public string AdvertStatus { get; set; } - public string Town { get; set; } - public string County { get; set; } - public decimal Price { get; set; } - public decimal? Mileage { get; set; } - public string FuelType { get; set; } - public string Postcode { get; set; } - } - public class NewsArticle - { - public string Title { get; set; } - public string Link { get; set; } - public string Copyright { get; set; } - public string Description { get; set; } - public DateTime PublishDateTime { get; set; } - public string FileName { get; set; } - } - - public static class ReaderExtensions - { - public static T GetValueOrDefault(this SqlDataReader reader, string fieldName) + + var solr = ServiceLocator.Current.GetInstance>>(); + int counter = 0; + foreach (var newsArticle in newsArticles) + { + string secondarySort = counter % 2 == 0 ? "A" : "B"; + counter++; + var item = new Dictionary + { + { "_uniqueid", newsArticle.Key ?? "" }, + { "title", newsArticle.Title ?? "" }, + { "link", newsArticle.Link ?? "" }, + { "copyright", newsArticle.Copyright ?? "" }, + { "description", newsArticle.Description ?? ""}, + { "publish_date_time", TestHelpers.GetDateString(newsArticle.PublishDateTime) }, + { "file_name", newsArticle.FileName ?? "" }, + { "secondary_sort", secondarySort } + + }; + + solr.Add(item); + solr.Commit(); + } + } + + + protected List ReadFeed(string filePath) { - if (reader[fieldName] == DBNull.Value) + List newsArticles = new List(); + using (var fileStream = File.OpenText(filePath)) { - return default(T); + var element = XElement.Load(fileStream); + var channel = element.Element("channel"); + if (channel == null) + { + return null; + } + + foreach (var node in channel.Elements("item")) + { + NewsArticle newsArticle = new NewsArticle(); + XElement descriptionElement = node.Element("description"); + if (descriptionElement != null) + { + newsArticle.Description = descriptionElement.Value.Trim(); + } + + var titleElement = node.Element("title"); + if (titleElement != null) + { + newsArticle.Title = titleElement.Value; + } + + var linkElement = node.Element("link"); + if (linkElement != null) + { + newsArticle.Link = linkElement.Value; + } + + var publishDateElement = node.Element("pubDate"); + if (publishDateElement != null) + { + newsArticle.PublishDateTime = DateTime.Parse(publishDateElement.Value); + } + + newsArticles.Add(newsArticle); + } } - return (T)reader[fieldName]; + + return newsArticles; } + + #endregion + + + public class CarDataItem + { + public Guid AdvertId { get; set; } + public DateTime Created { get; set; } + public int MakeId { get; set; } + public int ModelId { get; set; } + public string Code { get; set; } + public string Make { get; set; } + public string Model { get; set; } + public string Variant { get; set; } + public string Options { get; set; } + public int AdvertTypeId { get; set; } + public string AdvertType { get; set; } + public int AdvertStatusId { get; set; } + public string AdvertStatus { get; set; } + public string Town { get; set; } + public string County { get; set; } + public decimal Price { get; set; } + public decimal? Mileage { get; set; } + public string FuelType { get; set; } + public string Postcode { get; set; } + } + + public class NewsArticle + { + + [SolrUniqueKey("_uniqueid")] public string Key { get; set; } + + [SolrField("title")] public string Title { get; set; } + + [SolrField("link")] public string Link { get; set; } + + [SolrField("copyright")] public string Copyright { get; set; } + + [SolrField("description")] public string Description { get; set; } + + [SolrField("publish_date_time")] public DateTime PublishDateTime { get; set; } + + [SolrField("file_name")] public string FileName { get; set; } + } + } } \ No newline at end of file diff --git a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/PrefixTests.cs b/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/PrefixTests.cs deleted file mode 100644 index 3d6242a..0000000 --- a/Unit Tests/Lucinq.Solr.UnitTests/IntegrationTests/PrefixTests.cs +++ /dev/null @@ -1,78 +0,0 @@ -namespace Lucinq.Solr.UnitTests.IntegrationTests -{ - using System; - using System.Collections.Generic; - using AutoMapper; - using Core.Enums; - using Core.Interfaces; - using Core.Querying; - using Lucene.Net.Documents; - using Lucene.Net.QueryParsers; - using Lucene30.Querying; - using NUnit.Framework; - - [TestFixture] - public class PrefixTests : BaseTestFixture - { - /// - /// Grab all articles that have titles that are prefixed with 'in pictures' and then perform - /// a wildcard search against those. Pre-filter the documents with a date range - /// - [Test] - public void InPicturesTest() - { - LuceneSearch luceneSearch = new LuceneSearch(IndexDirectory); - - IQueryBuilder queryBuilder = new QueryBuilder(); - - // The prefix query needs to work against a field that hasn't been tokenised/analysed to work. - queryBuilder.Setup( - x => x.PrefixedWith(BBCFields.Sortable, QueryParser.Escape("in pictures"), Matches.Always) - ); - - ILuceneSearchResult result = luceneSearch.Execute(queryBuilder); - IList data = Mapper.Map, IList>(result.GetTopItems()); - - WriteDocuments(data); - - Console.WriteLine("Searched {0} documents in {1} ms", result.TotalHits, result.ElapsedTimeMs); - Console.WriteLine(); - - Assert.AreNotEqual(0, result.TotalHits); - } - - // todo: NM - Fix filter - /* - /// - /// Grab all articles that have titles that are prefixed with 'in pictures' and then perform - /// a wildcard search against those. Pre-filter the documents with a date range - /// - [Test] - public void InPicturesWithSearchAndFilterTest() - { - LuceneSearch luceneSearch = new LuceneSearch(IndexDirectory); - - IQueryBuilder queryBuilder = new QueryBuilder(); - DateTime february = DateTime.Parse("01/01/2013"); - DateTime end = DateTime.Parse("31/01/2013"); - - // The prefix query needs to work against a field that hasn't been tokenised/analysed to work. - queryBuilder.Setup( - x => x.PrefixedWith(BBCFields.Sortable, QueryParser.Escape("in pictures"), Matches.Always), - x => x.WildCard(BBCFields.Description, "images", Matches.Always), - x => x.Filter(DateRangeFilter.Filter(BBCFields.PublishDateObject, february, end)) - ); - - ILuceneSearchResult result = luceneSearch.Execute(queryBuilder); - IList data = Mapper.Map, IList>(result.GetTopItems()); - - WriteDocuments(data); - - Console.WriteLine("Searched {0} documents in {1} ms", result.TotalHits, result.ElapsedTimeMs); - Console.WriteLine(); - - Assert.AreNotEqual(0, result.TotalHits); - } - */ - } -} diff --git a/Unit Tests/Lucinq.Solr.UnitTests/Lucinq.Solr.UnitTests.csproj b/Unit Tests/Lucinq.Solr.UnitTests/Lucinq.Solr.UnitTests.csproj index 4c4440b..8cd531f 100644 --- a/Unit Tests/Lucinq.Solr.UnitTests/Lucinq.Solr.UnitTests.csproj +++ b/Unit Tests/Lucinq.Solr.UnitTests/Lucinq.Solr.UnitTests.csproj @@ -1,5 +1,5 @@  - + Debug @@ -11,7 +11,7 @@ Properties Lucinq.Solr.UnitTests Lucinq.Solr.UnitTests - v4.5 + v4.6 512 ..\..\ true @@ -45,19 +45,32 @@ ..\..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll + + ..\..\packages\CommonServiceLocator.2.0.2\lib\net45\CommonServiceLocator.dll + + + ..\..\packages\SolrNet.1.0.19\lib\net46\CommonServiceLocator.SolrNet.dll + ..\..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll - - ..\..\packages\Lucene.Net.3.0.3\lib\NET40\Lucene.Net.dll + + ..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll ..\..\packages\NUnit.3.11.0\lib\net45\nunit.framework.dll + + ..\..\packages\SolrNet.Core.1.0.19\lib\net46\SolrNet.dll + + + + ..\..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll + @@ -68,29 +81,22 @@ - - - - - - - - - {8fc26db5-0277-49c8-9345-d53da0059a64} - Lucinq.Lucene30 + + {6e6ff124-6a8b-47a9-8169-b9101117b486} + Lucinq.Solr {4A37D121-9AC6-489D-B565-C353D85AFB73} diff --git a/Unit Tests/Lucinq.Solr.UnitTests/UnitTests/ConceptTests.cs b/Unit Tests/Lucinq.Solr.UnitTests/UnitTests/ConceptTests.cs deleted file mode 100644 index b8f52e1..0000000 --- a/Unit Tests/Lucinq.Solr.UnitTests/UnitTests/ConceptTests.cs +++ /dev/null @@ -1,263 +0,0 @@ -namespace Lucinq.Solr.UnitTests.UnitTests -{ - using System; - using System.Diagnostics; - using System.IO; - using Core.Querying; - using IntegrationTests; - using Lucene.Net.Index; - using Lucene.Net.Search; - using Lucene.Net.Store; - using Lucene30.Querying; - using NUnit.Framework; - - [TestFixture] - public class ConceptTests : BaseTestFixture - { - /// - /// Test to show the speed of opening / closing ram directory - /// - [Test] - public void OpeningClosingAll() - { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - Console.WriteLine("Opening FS Dir"); - FSDirectory fileSystemDirectory = FSDirectory.Open(new DirectoryInfo(GeneralConstants.Paths.CarDataIndex)); - WriteTime(stopwatch); - Console.WriteLine("Opening Ram Dir"); - RAMDirectory ramDirectory = new RAMDirectory(fileSystemDirectory); - WriteTime(stopwatch); - ramDirectory.Dispose(); - WriteTime(stopwatch); - Console.WriteLine("Disposed Ram Dir"); - fileSystemDirectory.Dispose(); - WriteTime(stopwatch); - Console.WriteLine("Disposed FS Dir"); - stopwatch.Stop(); - } - - /// - /// Test to show the speed of opening / closing fs directory - /// - [Test] - public void OpeningClosingFsOnlyObjects() - { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - Console.WriteLine("Opening FS Dir"); - FSDirectory fileSystemDirectory = FSDirectory.Open(new DirectoryInfo(GeneralConstants.Paths.CarDataIndex)); - WriteTime(stopwatch); - fileSystemDirectory.Dispose(); - WriteTime(stopwatch); - Console.WriteLine("Disposed FS Dir"); - stopwatch.Stop(); - } - - - [Test] - public void OpenCloseOpenClose() - { - OpeningClosingAll(); - OpeningClosingAll(); - OpeningClosingAll(); - OpeningClosingAll(); - OpeningClosingAll(); - OpeningClosingAll(); - OpeningClosingAll(); - OpeningClosingAll(); - OpeningClosingAll(); - } - - [Test] - public void OpenCloseFsOnly() - { - OpeningClosingFsOnlyObjects(); - OpeningClosingFsOnlyObjects(); - OpeningClosingFsOnlyObjects(); - OpeningClosingFsOnlyObjects(); - OpeningClosingFsOnlyObjects(); - OpeningClosingFsOnlyObjects(); - OpeningClosingFsOnlyObjects(); - OpeningClosingFsOnlyObjects(); - } - - // todo: NM - Fix Raw - /* - - [Test] - public void LuceneObjectsIntoLucinq() - { - LuceneSearch search = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false)); - // raw lucene object - TermQuery query = new TermQuery(new Term(BBCFields.Title, "africa")); - - // executed directly by the search - ILuceneSearchResult result = search.Execute(query); - Assert.AreEqual(8, result.TotalHits); - - // or by through a querybuilder - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Add(query, Matches.Always); - ILuceneSearchResult result2 = search.Execute(queryBuilder); - Assert.AreEqual(8, result2.TotalHits); - } - */ - [Test] - public void BuiltIndexDisposed() - { - LuceneSearch luceneSearch = new LuceneSearch(IndexDirectory); - QueryBuilder qb = new QueryBuilder(x => x.Term(BBCFields.Title, "africa")); - var result = luceneSearch.Execute(qb); - result.GetRange(0, 10); - result.GetTopItems(); - } - - [Test] - public void ConvertBetweenQueries() - { - var conversion = new Conversion(); - FuzzyQuery query1 = conversion.Fuzzy1(); - Console.WriteLine(query1.ToString()); - - FuzzyQuery query2 = conversion.Fuzzy2(); - Console.WriteLine(query2.ToString()); - - FuzzyQuery query3 = conversion.Fuzzy3(); - Console.WriteLine(query3.ToString()); - } - - - public class Conversion : ConversionBase - { - public Conversion() - : this(new QueryOperations()) - { - - } - - public Conversion(IQueryOperations operations) - { - QueryOperations = operations; - } - - public FuzzyQuery Fuzzy1() - { - FuzzyQuery query = new FuzzyQuery(new Term("fred")); - return this.GetFuzzy1(query, 2.0f); - } - - public FuzzyQuery Fuzzy2() - { - FuzzyQuery query = new FuzzyQuery(new Term("fred")); - return this.GetFuzzy2(GetWrappedQuery(query), 2.0f); - } - - public FuzzyQuery Fuzzy3() - { - FuzzyQuery query = new FuzzyQuery(new Term("fred")); - return this.GetFuzzy3(query, 2.0f); - } - - private IQueryWrapper GetWrappedQuery(T query) where T : Query - { - return new QueryWrapper(query); - } - - protected override IQueryOperations QueryOperations { get; set; } - - protected override void SetBoostValue(Query query, float boost) - { - query.Boost = boost; - } - } - - public abstract class ConversionBase - { - protected abstract IQueryOperations QueryOperations { get; set; } - - protected TActualQuery GetFuzzy1(TActualQuery query, float boost) - where TActualQuery : class, TQuery - { - - this.SetBoostValue(query, boost); - return query; - } - - protected TActualQuery GetFuzzy3(TActualQuery query, float boost) - where TActualQuery : class, TQuery - { - this.QueryOperations.SetBoost(query, 2.0f); - return query; - } - - protected TActualQuery GetFuzzy2(IQueryWrapper queryAdapter, float boost) - where TActualQuery : class, TQuery - { - queryAdapter.SetBoostValue(boost); - return queryAdapter.Query; - } - - protected abstract void SetBoostValue(TQuery query, float boost); - } - - public class QueryOperations : IQueryOperations - { - public void SetBoost(object query, float boost) - { - Query actualQuery = query as Query; - if (actualQuery == null) - { - return; - } - actualQuery.Boost = boost; - } - - public void SetSlop(object query, int slop) - { - PhraseQuery actualQuery = query as PhraseQuery; - if (actualQuery == null) - { - return; - } - actualQuery.Slop = slop; - } - } - - public interface IQueryOperations - { - void SetBoost(object query, float boost); - - void SetSlop(object query, int slop); - } - - public class QueryWrapper : IQueryWrapper - where TQuery : Query - { - public QueryWrapper(TQuery query) - { - Query = query; - } - - public TQuery Query { get; private set; } - - public void SetBoostValue(float boost) - { - Query.Boost = boost; - } - } - - public interface IQueryWrapper - { - TQuery Query { get; } - - void SetBoostValue(float boost); - } - - private void WriteTime(Stopwatch stopwatch) - { - Console.Write(stopwatch.ElapsedTicks + " - "); - Console.Write(stopwatch.ElapsedMilliseconds + "\r\n"); - } - } -} diff --git a/Unit Tests/Lucinq.Solr.UnitTests/UnitTests/EquivalencyTests.cs b/Unit Tests/Lucinq.Solr.UnitTests/UnitTests/EquivalencyTests.cs index 039bb0a..de7855e 100644 --- a/Unit Tests/Lucinq.Solr.UnitTests/UnitTests/EquivalencyTests.cs +++ b/Unit Tests/Lucinq.Solr.UnitTests/UnitTests/EquivalencyTests.cs @@ -2,16 +2,10 @@ { using System; using System.Collections.Generic; + using Adapters; using Core.Enums; using Core.Querying; - using Lucene.Net.Analysis; - using Lucene.Net.Index; - using Lucene.Net.QueryParsers; - using Lucene.Net.Search; - using Lucene30.Adapters; - using Lucene30.Extensions; using NUnit.Framework; - using Version = Lucene.Net.Util.Version; [TestFixture] public class EquivalencyTests @@ -21,178 +15,140 @@ public class EquivalencyTests [Test] public void CaseInsensitiveMandatoryTerm() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "value"); - TermQuery termQuery = new TermQuery(term); - originalQuery.Add(termQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "+_name:value"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.Term("_name", "Value")); - LucinqQueryModel replacementQuery = builder.Build(); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void BoostedCaseInsensitiveMandatoryTerm() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "value"); - TermQuery termQuery = new TermQuery(term); - originalQuery.Add(termQuery, Matches.Always.GetLuceneOccurance()); - termQuery.Boost = 10; - string queryString = originalQuery.ToString(); + string queryString = "+_name:value~10"; QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.Term("_name", "Value", boost:10)); - LucinqQueryModel replacementQuery = builder.Build(); + builder.Setup(x => x.Term("_name", "Value", boost: 10)); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void CaseSensitiveMandatoryTerm() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "Value"); - TermQuery termQuery = new TermQuery(term); - originalQuery.Add(termQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - + string queryString = "+_name:Value"; QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.Term("_name", "Value", caseSensitive:true)); - LucinqQueryModel replacementQuery = builder.Build(); + builder.Setup(x => x.Term("_name", "Value", caseSensitive: true)); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void QueryCaseSensitiveMandatoryTerm() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "Value"); - TermQuery termQuery = new TermQuery(term); - originalQuery.Add(termQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "+_name:Value"; - - QueryBuilder builder = new QueryBuilder{CaseSensitive = true}; + QueryBuilder builder = new QueryBuilder { CaseSensitive = true }; builder.Setup(x => x.Term("_name", "Value")); - LucinqQueryModel replacementQuery = builder.Build(); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void CaseInsensitiveNonMandatoryTerm() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "value"); - TermQuery termQuery = new TermQuery(term); - originalQuery.Add(termQuery, Matches.Sometimes.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - + string queryString = "_name:value"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.Term("_name", "Value", Matches.Sometimes)); - LucinqQueryModel replacementQuery = builder.Build(); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void CaseSensitiveNonMandatoryTerm() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "Value"); - TermQuery termQuery = new TermQuery(term); - originalQuery.Add(termQuery, Matches.Sometimes.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "_name:Value"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.Term("_name", "Value", Matches.Sometimes, caseSensitive: true)); - LucinqQueryModel replacementQuery = builder.Build(); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } - [Test] - public void CaseInsensitiveNotTerm() - { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "value"); - TermQuery termQuery = new TermQuery(term); - originalQuery.Add(termQuery, Matches.Never.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - - - QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.Term("_name", "Value", Matches.Never)); - LucinqQueryModel replacementQuery = builder.Build(); + [Test] + public void CaseInsensitiveNotTerm() + { + string queryString = "-_name:value"; - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + QueryBuilder builder = new QueryBuilder(); + builder.Setup(x => x.Term("_name", "Value", Matches.Never)); + LucinqQueryModel replacementQuery = builder.Build(); - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - [Test] - public void CaseSensitiveNotTerm() - { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "Value"); - TermQuery termQuery = new TermQuery(term); - originalQuery.Add(termQuery, Matches.Never.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } + [Test] + public void CaseSensitiveNotTerm() + { + string queryString = "-_name:Value"; - QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.Term("_name", "Value", Matches.Never, caseSensitive: true)); - LucinqQueryModel replacementQuery = builder.Build(); + QueryBuilder builder = new QueryBuilder(); + builder.Setup(x => x.Term("_name", "Value", Matches.Never, caseSensitive: true)); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } #endregion #region [ Lucene Tests ] - // todo: NM: Fix raw - /* + // todo: NM: Fix raw + /* [Test] public void AddLuceneApiQuery() { @@ -221,107 +177,83 @@ public void AddLuceneApiQuery() [Test] public void CaseInsensitivePhrase() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "value"); - PhraseQuery phraseQuery = new PhraseQuery {Slop = 2}; - phraseQuery.Add(term); - originalQuery.Add(phraseQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - + string queryString = "+_name:\"value\"~2"; QueryBuilder builder = new QueryBuilder(); - var terms = new[] - { - new KeyValuePair("_name", "value") - }; + var terms = new[] + { + new KeyValuePair("_name", "value") + }; builder.Setup(x => x.Phrase(2, terms)); - LucinqQueryModel replacementQuery = builder.Build(); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void BoostedCaseInsensitivePhrase() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "value"); - PhraseQuery phraseQuery = new PhraseQuery {Slop = 2}; - phraseQuery.Add(term); - phraseQuery.Boost = 10; - originalQuery.Add(phraseQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - + string queryString = "+_name:\"value\"~2^10"; QueryBuilder builder = new QueryBuilder(); - var terms = new[] - { - new KeyValuePair("_name", "Value") - }; + var terms = new[] + { + new KeyValuePair("_name", "Value") + }; builder.Setup(x => x.Phrase(2, terms, 10)); - LucinqQueryModel replacementQuery = builder.Build(); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void CaseSensitivePhrase() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "Value"); - PhraseQuery phraseQuery = new PhraseQuery {Slop = 2}; - phraseQuery.Add(term); - originalQuery.Add(phraseQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "+_name:\"Value\"~2"; - QueryBuilder builder = new QueryBuilder{CaseSensitive = true}; - var terms = new[] - { - new KeyValuePair("_name", "Value") - }; + QueryBuilder builder = new QueryBuilder { CaseSensitive = true }; + var terms = new[] + { + new KeyValuePair("_name", "Value") + }; builder.Setup(x => x.Phrase(2, terms)); - LucinqQueryModel replacementQuery = builder.Build(); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void QueryCaseSensitivePhrase() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "Value"); - PhraseQuery phraseQuery = new PhraseQuery {Slop = 2}; - phraseQuery.Add(term); - originalQuery.Add(phraseQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - + string queryString = "+_name:\"Value\"~2"; - QueryBuilder builder = new QueryBuilder{CaseSensitive = true}; - var terms = new[] - { - new KeyValuePair("_name", "Value") - }; + QueryBuilder builder = new QueryBuilder { CaseSensitive = true }; + var terms = new[] + { + new KeyValuePair("_name", "Value") + }; builder.Setup(x => x.Phrase(2, terms)); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } @@ -332,311 +264,165 @@ public void QueryCaseSensitivePhrase() [Test] public void CaseInsensitiveMandatoryWildCard() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "value*"); - WildcardQuery wildcardQuery = new WildcardQuery(term); - originalQuery.Add(wildcardQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "+_name:value*"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.WildCard("_name", "Value*")); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void CaseSensitiveMandatoryWildCard() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "Value*"); - WildcardQuery wildcardQuery = new WildcardQuery(term); - originalQuery.Add(wildcardQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "+_name:Value*"; QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.WildCard("_name", "Value*", caseSensitive:true)); + builder.Setup(x => x.WildCard("_name", "Value*", caseSensitive: true)); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void QueryCaseSensitiveMandatoryWildCard() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "Value*"); - WildcardQuery wildcardQuery = new WildcardQuery(term); - originalQuery.Add(wildcardQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "+_name:Value*"; - QueryBuilder builder = new QueryBuilder{CaseSensitive = true}; + QueryBuilder builder = new QueryBuilder { CaseSensitive = true }; builder.Setup(x => x.WildCard("_name", "Value*")); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void CaseInsensitiveNonMandatoryWildCard() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "value*"); - WildcardQuery wildcardQuery = new WildcardQuery(term); - originalQuery.Add(wildcardQuery, Matches.Sometimes.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "_name:value*"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.WildCard("_name", "Value*", Matches.Sometimes)); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void CaseSensitiveNonMandatoryWildCard() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "Value*"); - WildcardQuery wildcardQuery = new WildcardQuery(term); - originalQuery.Add(wildcardQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "_name:Value*"; QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.WildCard("_name", "Value*", caseSensitive: true)); + builder.Setup(x => x.WildCard("_name", "Value*", Matches.Sometimes, caseSensitive: true)); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } - [Test] - public void CaseInsensitiveWildCards() - { - BooleanQuery originalQuery = new BooleanQuery(); - BooleanQuery innerQuery = new BooleanQuery(); - Term term = new Term("_name", "value*"); - WildcardQuery wildcardQuery = new WildcardQuery(term); - innerQuery.Add(wildcardQuery, Matches.Always.GetLuceneOccurance()); - - Term term2 = new Term("_name", "value2*"); - WildcardQuery wildcardQuery2 = new WildcardQuery(term2); - innerQuery.Add(wildcardQuery2, Matches.Always.GetLuceneOccurance()); - originalQuery.Add(innerQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - - QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.WildCards("_name", new []{"Value*", "Value2*"})); - LucinqQueryModel replacementQuery = builder.Build(); - - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); - - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } - - #endregion - - #region [ Fuzzy Tests ] - - [Test] - public void CaseInsensitiveMandatoryFuzzy() - { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "value*"); - FuzzyQuery fuzzyQuery = new FuzzyQuery(term, 0.9f); - originalQuery.Add(fuzzyQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - - QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.Fuzzy("_name", "Value*", 0.9f)); - LucinqQueryModel replacementQuery = builder.Build(); - - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); - - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } - - [Test] - public void CaseSensitiveMandatoryFuzzy() - { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "Value*"); - FuzzyQuery fuzzyQuery = new FuzzyQuery(term, 0.9f); - originalQuery.Add(fuzzyQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - - QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.Fuzzy("_name", "Value*", 0.9f, caseSensitive: true)); - LucinqQueryModel replacementQuery = builder.Build(); - - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); - - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } - - [Test] - public void QueryCaseSensitiveMandatoryFuzzy() - { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "Value*"); - FuzzyQuery wildcardQuery = new FuzzyQuery(term, 0.9f); - originalQuery.Add(wildcardQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - - QueryBuilder builder = new QueryBuilder { CaseSensitive = true }; - builder.Setup(x => x.Fuzzy("_name", "Value*", 0.9f)); - LucinqQueryModel replacementQuery = builder.Build(); - - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); - - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } - - [Test] - public void CaseInsensitiveNonMandatoryFuzzy() - { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "value*"); - FuzzyQuery fuzzyQuery = new FuzzyQuery(term, 0.9f); - originalQuery.Add(fuzzyQuery, Matches.Sometimes.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - - QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.Fuzzy("_name", "Value*", 0.9f, Matches.Sometimes)); - LucinqQueryModel replacementQuery = builder.Build(); - - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); - - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } - - [Test] - public void CaseSensitiveNonMandatoryFuzzy() - { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "Value*"); - FuzzyQuery fuzzyQuery = new FuzzyQuery(term, 0.9f); - originalQuery.Add(fuzzyQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + [Test] + public void CaseInsensitiveWildCards() + { + string queryString = "( +_name:value* AND +_name:value2*)"; - QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.Fuzzy("_name", "Value*", 0.9f, caseSensitive: true)); - LucinqQueryModel replacementQuery = builder.Build(); + QueryBuilder builder = new QueryBuilder(); + builder.Setup(x => x.WildCards("_name", new[] { "Value*", "Value2*" })); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } - #endregion + #endregion - #region [ Term Range Tests ] + #region [ Term Range Tests ] - [Test] + [Test] public void CaseInSensitiveTermRange() { - BooleanQuery originalQuery = new BooleanQuery(); - TermRangeQuery termRangeQuery = new TermRangeQuery("field", "lower", "upper", true, true); - originalQuery.Add(termRangeQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "field:[lower TO upper]"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.TermRange("field", "Lower", "Upper")); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).FilterBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void CaseSensitiveTermRange() { - BooleanQuery originalQuery = new BooleanQuery(); - TermRangeQuery termRangeQuery = new TermRangeQuery("field", "Lower", "Upper", true, true); - originalQuery.Add(termRangeQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "field:[Lower TO Upper]"; QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.TermRange("field", "Lower", "Upper", caseSensitive:true)); + builder.Setup(x => x.TermRange("field", "Lower", "Upper", caseSensitive: true)); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).FilterBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } - [Test] - public void CaseInsensitiveTermRange() - { - BooleanQuery originalQuery = new BooleanQuery(); - TermRangeQuery termRangeQuery = new TermRangeQuery("field", "lower", "upper", true, true); - originalQuery.Add(termRangeQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + [Test] + public void CaseInsensitiveTermRange() + { + string queryString = "field:[lower TO upper]"; - QueryBuilder builder = new QueryBuilder(); - builder.Setup(x => x.TermRange("field", "Lower", "Upper", caseSensitive: false)); - LucinqQueryModel replacementQuery = builder.Build(); + QueryBuilder builder = new QueryBuilder(); + builder.Setup(x => x.TermRange("field", "Lower", "Upper", caseSensitive: false)); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).FilterBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } [Test] public void QueryCaseSensitiveTermRange() - { - BooleanQuery originalQuery = new BooleanQuery(); - TermRangeQuery termRangeQuery = new TermRangeQuery("field", "Lower", "Upper", true, true); - originalQuery.Add(termRangeQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + { + string queryString = "field:[Lower TO Upper]"; - QueryBuilder builder = new QueryBuilder{CaseSensitive = true}; + QueryBuilder builder = new QueryBuilder { CaseSensitive = true }; builder.Setup(x => x.TermRange("field", "Lower", "Upper")); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).FilterBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } @@ -649,19 +435,16 @@ public void CaseInsensitiveKeyword() { QueryBuilder builder = new QueryBuilder(); - BooleanQuery originalQuery = new BooleanQuery(); - QueryParser rawQueryParser = new QueryParser(Version.LUCENE_29, "_name", new KeywordAnalyzer()); - originalQuery.Add(rawQueryParser.Parse("value"), Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "+_name:\"value\""; builder.Setup(x => x.Keyword("_name", "Value")); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } @@ -670,19 +453,16 @@ public void CaseSensitiveKeyword() { QueryBuilder builder = new QueryBuilder(); - BooleanQuery originalQuery = new BooleanQuery(); - QueryParser rawQueryParser = new QueryParser(Version.LUCENE_29, "_name", new KeywordAnalyzer()); - originalQuery.Add(rawQueryParser.Parse("Value"), Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "+_name:\"Value\""; - builder.Setup(x => x.Keyword("_name", "Value", caseSensitive:true)); + builder.Setup(x => x.Keyword("_name", "Value", caseSensitive: true)); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } @@ -692,18 +472,14 @@ public void CaseInsensitiveNonMandatoryKeyword() { QueryBuilder builder = new QueryBuilder(); - BooleanQuery originalQuery = new BooleanQuery(); - QueryParser rawQueryParser = new QueryParser(Version.LUCENE_29, "_name", new KeywordAnalyzer()); - originalQuery.Add(rawQueryParser.Parse("value"), Matches.Sometimes.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - + string queryString = "_name:\"value\""; builder.Setup(x => x.Keyword("_name", "Value", Matches.Sometimes)); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } @@ -712,46 +488,34 @@ public void CaseSensitiveNonMandatoryKeyword() { QueryBuilder builder = new QueryBuilder(); - BooleanQuery originalQuery = new BooleanQuery(); - QueryParser rawQueryParser = new QueryParser(Version.LUCENE_29, "_name", new KeywordAnalyzer()); - originalQuery.Add(rawQueryParser.Parse("Value"), Matches.Sometimes.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - + string queryString = "_name:\"Value\""; builder.Setup(x => x.Keyword("_name", "Value", Matches.Sometimes, caseSensitive: true)); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } - [Test] - public void CaseInsensitiveKeywords() - { - QueryBuilder builder = new QueryBuilder(); + [Test] + public void CaseInsensitiveKeywords() + { + QueryBuilder builder = new QueryBuilder(); - BooleanQuery originalQuery = new BooleanQuery(); - BooleanQuery innerQuery = new BooleanQuery(); - QueryParser rawQueryParser = new QueryParser(Version.LUCENE_29, "_name", new KeywordAnalyzer()); - innerQuery.Add(rawQueryParser.Parse("value"), Matches.Always.GetLuceneOccurance()); - innerQuery.Add(rawQueryParser.Parse("value2"), Matches.Always.GetLuceneOccurance()); - innerQuery.Add(rawQueryParser.Parse("value3"), Matches.Always.GetLuceneOccurance()); - originalQuery.Add(innerQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); - originalQuery.Add(rawQueryParser.Parse("value2"), Matches.Always.GetLuceneOccurance()); + string queryString = "( +_name:\"value\" AND +_name:\"value2\" AND +_name:\"value3\")"; - builder.Setup(x => x.Keywords("_name", new []{"Value", "Value2", "Value3"})); - LucinqQueryModel replacementQuery = builder.Build(); + builder.Setup(x => x.Keywords("_name", new[] { "Value", "Value2", "Value3" })); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } #endregion @@ -760,57 +524,47 @@ public void CaseInsensitiveKeywords() [Test] public void IntegerRange() { - BooleanQuery originalQuery = new BooleanQuery(); - NumericRangeQuery numericRangeQuery = NumericRangeQuery.NewIntRange("field", 1, 0, 10, true, true); - originalQuery.Add(numericRangeQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "field:[0 TO 10]"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.NumericRange("field", 0, 10)); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).FilterBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void DoubleRange() { - BooleanQuery originalQuery = new BooleanQuery(); - NumericRangeQuery numericRangeQuery = NumericRangeQuery.NewDoubleRange("field", 1, 0d, 10d, true, true); - originalQuery.Add(numericRangeQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "field:[0 TO 10]"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.NumericRange("field", 0d, 10d)); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); - - Assert.AreEqual(queryString, newQueryString); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).FilterBuilder.ToString(); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } [Test] public void LongRange() { - BooleanQuery originalQuery = new BooleanQuery(); - NumericRangeQuery numericRangeQuery = NumericRangeQuery.NewLongRange("field", 1, 0L, 10L, true, true); - originalQuery.Add(numericRangeQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "field:[0 TO 10]"; QueryBuilder builder = new QueryBuilder(); builder.Setup(x => x.NumericRange("field", 0L, 10L)); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).FilterBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } @@ -821,30 +575,20 @@ public void LongRange() [Test] public void Or() { - BooleanQuery originalQuery = new BooleanQuery(); - - Term term = new Term("_name", "value1"); - TermQuery termQuery1 = new TermQuery(term); - originalQuery.Add(termQuery1, Matches.Sometimes.GetLuceneOccurance()); + string queryString = "_name:value1 _name:value2"; - Term term2 = new Term("_name", "value2"); - TermQuery termQuery2 = new TermQuery(term2); - originalQuery.Add(termQuery2, Matches.Sometimes.GetLuceneOccurance()); - - string queryString = originalQuery.ToString(); - - QueryBuilder builder = new QueryBuilder{DefaultChildrenOccur = Matches.Sometimes}; + QueryBuilder builder = new QueryBuilder { DefaultChildrenOccur = Matches.Sometimes }; builder.Setup ( x => x.Term("_name", "value1"), x => x.Term("_name", "value2") ); LucinqQueryModel replacementQuery1 = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); - string newQueryString1 = adapter.Adapt(replacementQuery1).Query.ToString(); + string newQueryString1 = adapter.Adapt(replacementQuery1).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString1); + Assert.AreEqual(queryString, newQueryString1); QueryBuilder builder2 = new QueryBuilder(); builder2.Setup @@ -853,9 +597,9 @@ public void Or() x => x.Term("_name", "value2", Matches.Sometimes) ); LucinqQueryModel replacementQuery2 = builder2.Build(); - string newQueryString2 = adapter.Adapt(replacementQuery2).Query.ToString(); + string newQueryString2 = adapter.Adapt(replacementQuery2).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString2); + Assert.AreEqual(queryString, newQueryString2); QueryBuilder builder3 = new QueryBuilder(); builder3.Setup @@ -864,62 +608,37 @@ public void Or() x => x.Term("_name", "value2") ); LucinqQueryModel replacementQuery3 = builder3.Build(); - string newQueryString3 = adapter.Adapt(replacementQuery3).Query.ToString(); + string newQueryString3 = adapter.Adapt(replacementQuery3).QueryBuilder.ToString(); Assert.AreNotEqual(queryString, newQueryString3); - + Console.Write(queryString); } - [Test] - public void OptionalOr() - { - BooleanQuery originalQuery = new BooleanQuery(); - - BooleanQuery innerQuery = new BooleanQuery(); - - Term term = new Term("_name", "value1"); - TermQuery termQuery1 = new TermQuery(term); - innerQuery.Add(termQuery1, Matches.Sometimes.GetLuceneOccurance()); - - Term term2 = new Term("_name", "value2"); - TermQuery termQuery2 = new TermQuery(term2); - innerQuery.Add(termQuery2, Matches.Sometimes.GetLuceneOccurance()); - originalQuery.Add(innerQuery, Matches.Sometimes.GetLuceneOccurance()); - - string queryString = originalQuery.ToString(); + [Test] + public void OptionalOr() + { + string queryString = "( _name:value1 OR _name:value2)"; - QueryBuilder builder = new QueryBuilder { DefaultChildrenOccur = Matches.Sometimes }; - builder.Or - ( - Matches.Sometimes, - x => x.Term("_name", "value1"), - x => x.Term("_name", "value2") - ); - LucinqQueryModel replacementQuery = builder.Build(); + QueryBuilder builder = new QueryBuilder { DefaultChildrenOccur = Matches.Sometimes }; + builder.Or + ( + Matches.Sometimes, + x => x.Term("_name", "value1"), + x => x.Term("_name", "value2") + ); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString1 = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString1 = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString1); - } + Assert.AreEqual(queryString, newQueryString1); + } [Test] public void OrExtension() { - BooleanQuery originalQuery = new BooleanQuery(); - BooleanQuery innerQuery = new BooleanQuery(); - - Term term = new Term("_name", "value1"); - TermQuery termQuery1 = new TermQuery(term); - innerQuery.Add(termQuery1, Matches.Sometimes.GetLuceneOccurance()); - - Term term2 = new Term("_name", "value2"); - TermQuery termQuery2 = new TermQuery(term2); - innerQuery.Add(termQuery2, Matches.Sometimes.GetLuceneOccurance()); - - originalQuery.Add(innerQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "( _name:value1 OR _name:value2)"; QueryBuilder builder = new QueryBuilder(); var builder2 = builder.Or @@ -928,65 +647,41 @@ public void OrExtension() x => x.Term("_name", "value2") ); - Assert.AreEqual(builder2, builder); +// Assert.AreEqual(builder2, builder); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } - [Test] - public void CreateOrExtension() - { - BooleanQuery originalQuery = new BooleanQuery(); - BooleanQuery innerQuery = new BooleanQuery(); - - Term term = new Term("_name", "value1"); - TermQuery termQuery1 = new TermQuery(term); - innerQuery.Add(termQuery1, Matches.Sometimes.GetLuceneOccurance()); - - Term term2 = new Term("_name", "value2"); - TermQuery termQuery2 = new TermQuery(term2); - innerQuery.Add(termQuery2, Matches.Sometimes.GetLuceneOccurance()); - - originalQuery.Add(innerQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + [Test] + public void CreateOrExtension() + { + string queryString = "( _name:value1 OR _name:value2)"; - QueryBuilder builder = new QueryBuilder(); - var group = builder.CreateOrGroup - ( - x => x.Term("_name", "value1"), - x => x.Term("_name", "value2") - ); - Assert.AreNotEqual(group, builder); - LucinqQueryModel replacementQuery = builder.Build(); + QueryBuilder builder = new QueryBuilder(); + var group = builder.CreateOrGroup + ( + x => x.Term("_name", "value1"), + x => x.Term("_name", "value2") + ); + Assert.AreNotEqual(group, builder); + LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } [Test] public void AndExtension() { - BooleanQuery originalQuery = new BooleanQuery(); - BooleanQuery innerQuery = new BooleanQuery(); - - Term term = new Term("_name", "value1"); - TermQuery termQuery1 = new TermQuery(term); - innerQuery.Add(termQuery1, Matches.Always.GetLuceneOccurance()); - - Term term2 = new Term("_name", "value2"); - TermQuery termQuery2 = new TermQuery(term2); - innerQuery.Add(termQuery2, Matches.Always.GetLuceneOccurance()); - - originalQuery.Add(innerQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + string queryString = "( +_name:value1 AND +_name:value2)"; QueryBuilder builder = new QueryBuilder(); var builder2 = builder.And @@ -995,82 +690,94 @@ public void AndExtension() x => x.Term("_name", "value2") ); - Assert.AreEqual(builder2, builder); + /*Assert.AreEqual(builder2, builder);*/ LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } - [Test] - public void CreateAndExtension() - { - BooleanQuery originalQuery = new BooleanQuery(); - BooleanQuery innerQuery = new BooleanQuery(); + [Test] + public void CreateAndExtension() + { + string queryString = "( +_name:value1 AND +_name:value2)"; - Term term = new Term("_name", "value1"); - TermQuery termQuery1 = new TermQuery(term); - innerQuery.Add(termQuery1, Matches.Always.GetLuceneOccurance()); + QueryBuilder builder = new QueryBuilder(); + var builder2 = builder.CreateAndGroup + ( + x => x.Term("_name", "value1"), + x => x.Term("_name", "value2") + ); - Term term2 = new Term("_name", "value2"); - TermQuery termQuery2 = new TermQuery(term2); - innerQuery.Add(termQuery2, Matches.Always.GetLuceneOccurance()); + Assert.AreNotEqual(builder2, builder); + LucinqQueryModel replacementQuery = builder.Build(); - originalQuery.Add(innerQuery, Matches.Always.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - QueryBuilder builder = new QueryBuilder(); - var builder2 = builder.CreateAndGroup - ( - x => x.Term("_name", "value1"), - x => x.Term("_name", "value2") - ); + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } - Assert.AreNotEqual(builder2, builder); - LucinqQueryModel replacementQuery = builder.Build(); + [Test] + public void OptionalAndExtension() + { + string queryString = "( +_name:value1 AND +_name:value2)"; - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + QueryBuilder builder = new QueryBuilder(); + builder.And + ( + Matches.Sometimes, + x => x.Term("_name", "value1"), + x => x.Term("_name", "value2") + ); + LucinqQueryModel replacementQuery = builder.Build(); - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - [Test] - public void OptionalAndExtension() - { - BooleanQuery originalQuery = new BooleanQuery(); - BooleanQuery innerQuery = new BooleanQuery(); + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } - Term term = new Term("_name", "value1"); - TermQuery termQuery1 = new TermQuery(term); - innerQuery.Add(termQuery1, Matches.Always.GetLuceneOccurance()); + [Test] + public void Filter() + { + string filterString = "name1:value1"; - Term term2 = new Term("_name", "value2"); - TermQuery termQuery2 = new TermQuery(term2); - innerQuery.Add(termQuery2, Matches.Always.GetLuceneOccurance()); + QueryBuilder builder = new QueryBuilder(); + builder.Setup(x => x.Filter(new LucinqFilter("name1", "value1", Comparator.Equals))); + LucinqQueryModel replacementQuery = builder.Build(); - originalQuery.Add(innerQuery, Matches.Sometimes.GetLuceneOccurance()); - string queryString = originalQuery.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).FilterBuilder.ToString(); - QueryBuilder builder = new QueryBuilder(); - builder.And - ( - Matches.Sometimes, - x => x.Term("_name", "value1"), - x => x.Term("_name", "value2") - ); - LucinqQueryModel replacementQuery = builder.Build(); + Assert.AreEqual(filterString, newQueryString); + Console.Write(filterString); + } - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + [Test] + public void TermRangeAndFilter() + { + string filterString = "field:[Lower TO Upper] and name1:[value1 TO * ]"; - Assert.AreEqual(queryString, newQueryString); - Console.Write(queryString); - } + QueryBuilder builder = new QueryBuilder(); + builder.Setup(x => + { + x.TermRange("field", "Lower", "Upper", caseSensitive: true); + x.Filter(new LucinqFilter("name1", "value1", Comparator.GreaterThanEquals)); + }); + LucinqQueryModel replacementQuery = builder.Build(); + + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).FilterBuilder.ToString(); + + Assert.AreEqual(filterString, newQueryString); + Console.Write(filterString); + } #endregion @@ -1079,65 +786,49 @@ public void OptionalAndExtension() [Test] public void CompositeTermPhraseWildcardTests() { - BooleanQuery originalQuery = new BooleanQuery(); - Term term = new Term("_name", "value"); - TermQuery termQuery = new TermQuery(term); - originalQuery.Add(termQuery, Matches.Always.GetLuceneOccurance()); - PhraseQuery phraseQuery = new PhraseQuery(); - Term phraseTerm = new Term("_name", "phrase"); - phraseQuery.Slop = 2; - phraseQuery.Add(phraseTerm); - originalQuery.Add(phraseQuery, Matches.Always.GetLuceneOccurance()); - - Term wildcardTerm = new Term("_name", "*wildcard*"); - WildcardQuery wildcardQuery = new WildcardQuery(wildcardTerm); - originalQuery.Add(wildcardQuery, Matches.Sometimes.GetLuceneOccurance()); - - string queryString = originalQuery.ToString(); - - + string queryString = "+_name:value +_name:\"phrase\"~2 _name:*wildcard*"; QueryBuilder builder = new QueryBuilder(); builder.Setup ( x => x.Term("_name", "value"), - x => x.Phrase(2, new []{new KeyValuePair("_name", "phrase") }), + x => x.Phrase(2, new[] { new KeyValuePair("_name", "phrase") }), x => x.WildCard("_name", "*wildcard*", Matches.Sometimes) ); LucinqQueryModel replacementQuery = builder.Build(); - LuceneAdapter adapter = new LuceneAdapter(); - string newQueryString = adapter.Adapt(replacementQuery).Query.ToString(); + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); - Assert.AreEqual(queryString, newQueryString); + Assert.AreEqual(queryString, newQueryString); Console.Write(queryString); } #endregion - #region [ Constructor Tests ] + #region [ Constructor Tests ] - [Test] - public void SetupConstructorTest() - { - QueryBuilder setupBuilder = new QueryBuilder(); - setupBuilder.Setup(x => x.Term("_name", "Value")); - LucinqQueryModel setupQuery = setupBuilder.Build(); - string setupQueryString = setupQuery.ToString(); + [Test] + public void SetupConstructorTest() + { + QueryBuilder setupBuilder = new QueryBuilder(); + setupBuilder.Setup(x => x.Term("_name", "Value")); + LucinqQueryModel setupQuery = setupBuilder.Build(); + string setupQueryString = setupQuery.ToString(); - QueryBuilder constructorBuilder = new QueryBuilder(x => x.Term("_name", "Value")); - LucinqQueryModel constructorQuery = constructorBuilder.Build(); - string constructorQueryString = constructorQuery.ToString(); + QueryBuilder constructorBuilder = new QueryBuilder(x => x.Term("_name", "Value")); + LucinqQueryModel constructorQuery = constructorBuilder.Build(); + string constructorQueryString = constructorQuery.ToString(); - Assert.AreEqual(setupQueryString, constructorQueryString); - } + Assert.AreEqual(setupQueryString, constructorQueryString); + } - #endregion + #endregion - #region [ Raw Tests ] - - // todo: NM: Fix Raw - /* + #region [ Raw Tests ] + + // todo: NM: Fix Raw + /* [Test] public void RawWithAnalyzer() { @@ -1176,6 +867,194 @@ public void RawWithoutAnalyzer() } */ - #endregion - } + [Test] + public void AndFirst() + { + string queryString = "+_name:\"phrase\"~2 _name:*wildcard* AND ( +_name:value AND +_name:value)"; + + QueryBuilder builder = new QueryBuilder(); + var andGroup = builder.And(); + andGroup.Term("_name", "value"); + andGroup.Term("_name", "value"); + builder.Setup + ( + x => x.Phrase(2, new[] { new KeyValuePair("_name", "phrase") }), + x => x.WildCard("_name", "*wildcard*", Matches.Sometimes) + ); + LucinqQueryModel replacementQuery = builder.Build(); + + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); + + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } + + [Test] + public void AndOnly() + { + string queryString = "( +_name:value AND +_name:value)"; + + QueryBuilder builder = new QueryBuilder(); + var andGroup = builder.And(); + andGroup.Term("_name", "value"); + andGroup.Term("_name", "value"); + + LucinqQueryModel replacementQuery = builder.Build(); + + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); + + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } + + [Test] + public void AndThenAnd() + { + string queryString = "( +_name:value AND +_name:value) AND ( +_name:value AND +_name:value)"; + + QueryBuilder builder = new QueryBuilder(); + var andGroup1 = builder.And(); + andGroup1.Term("_name", "value"); + andGroup1.Term("_name", "value"); + + var andGroup2 = builder.And(); + andGroup2.Term("_name", "value"); + andGroup2.Term("_name", "value"); + + LucinqQueryModel replacementQuery = builder.Build(); + + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); + + + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } + + [Test] + public void NestedAnd() + { + string queryString = "( +_name:value AND +_name:value AND ( +_name:value AND +_name:value))"; + + QueryBuilder builder = new QueryBuilder(); + var andGroup1 = builder.And(); + andGroup1.Term("_name", "value"); + andGroup1.Term("_name", "value"); + + var andGroup2 = andGroup1.And(); + andGroup2.Term("_name", "value"); + andGroup2.Term("_name", "value"); + + LucinqQueryModel replacementQuery = builder.Build(); + + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); + + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } + + [Test] + public void NestedAndOr() + { + string queryString = "( +_name:value AND +_name:value AND ( _name:value OR _name:value))"; + + QueryBuilder builder = new QueryBuilder(); + var andGroup1 = builder.And(); + andGroup1.Term("_name", "value"); + andGroup1.Term("_name", "value"); + + var orGroup2 = andGroup1.Or(); + orGroup2.Term("_name", "value"); + orGroup2.Term("_name", "value"); + + LucinqQueryModel replacementQuery = builder.Build(); + + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); + + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } + + [Test] + public void NestedOrAnd() + { + string queryString = "( _name:value OR _name:value AND ( +_name:value AND +_name:value))"; + + QueryBuilder builder = new QueryBuilder(); + var orGroup1 = builder.Or(); + orGroup1.Term("_name", "value"); + orGroup1.Term("_name", "value"); + + var andGroup2 = orGroup1.And(); + andGroup2.Term("_name", "value"); + andGroup2.Term("_name", "value"); + + LucinqQueryModel replacementQuery = builder.Build(); + + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); + + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } + + [Test] + public void NestedEmptyOrAnd() + { + string queryString = "( +_name:value AND +_name:value)"; + + QueryBuilder builder = new QueryBuilder(); + var orGroup1 = builder.Or(); + + var andGroup2 = orGroup1.And(); + andGroup2.Term("_name", "value"); + andGroup2.Term("_name", "value"); + + LucinqQueryModel replacementQuery = builder.Build(); + + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); + + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } + + [Test] + public void OrThenAnd() + { + string queryString = "( _name:value OR _name:value) AND ( +_name:value AND +_name:value)"; + + QueryBuilder builder = new QueryBuilder(); + var orGroup1 = builder.Or(); + orGroup1.Term("_name", "value"); + orGroup1.Term("_name", "value"); + + var andGroup2 = builder.And(); + andGroup2.Term("_name", "value"); + andGroup2.Term("_name", "value"); + + LucinqQueryModel replacementQuery = builder.Build(); + + SolrSearchAdapter adapter = new SolrSearchAdapter(); + string newQueryString = adapter.Adapt(replacementQuery).QueryBuilder.ToString(); + + Assert.AreEqual(queryString, newQueryString); + Console.Write(queryString); + } + + + #endregion + + [Test] + public void DateTimeFormatTest() + { + DateTime date = DateTime.Now.ToUniversalTime(); + string result = date.ToString("O"); + Console.WriteLine(result); + } + } } diff --git a/Unit Tests/Lucinq.Solr.UnitTests/UnitTests/ItemResultTests.cs b/Unit Tests/Lucinq.Solr.UnitTests/UnitTests/ItemResultTests.cs deleted file mode 100644 index 2041283..0000000 --- a/Unit Tests/Lucinq.Solr.UnitTests/UnitTests/ItemResultTests.cs +++ /dev/null @@ -1,167 +0,0 @@ -namespace Lucinq.Solr.UnitTests.UnitTests -{ - using System; - using AutoMapper; - using Core.Interfaces; - using Core.Querying; - using Core.Results; - using IntegrationTests; - using Lucene.Net.Documents; - using Lucene.Net.Store; - using Lucene30.Querying; - using NUnit.Framework; - - [TestFixture] - public class ItemResultTests : BaseTestFixture - { - [Test] - public void GetTopItemsFromDelegateResult() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false)); - IQueryBuilder queryBuilder = new QueryBuilder(); - - queryBuilder.Term(BBCFields.Title, "africa"); - var results = luceneSearch.Execute, NewsArticle>(queryBuilder, x => new DelegateItemSearchResult(x, GetNewsArticleFromDocument)); - var newsArticles = results.GetTopItems(); - Assert.Greater(results.TotalHits, 0); - foreach (var newsArticle in newsArticles) - { - Console.WriteLine(newsArticle.Title); - Assert.IsTrue(newsArticle.Title.IndexOf("africa", StringComparison.OrdinalIgnoreCase) >= 0); - } - } - - [Test] - public void GetTopItemsFromSpecificResult() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false)); - - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Term(BBCFields.Title, "africa"); - var results = luceneSearch.Execute(queryBuilder, x => new NewsArticleItemResult(x)); - var newsArticles = results.GetTopItems(); - Assert.Greater(results.TotalHits, 0); - foreach (var newsArticle in newsArticles) - { - Assert.IsTrue(newsArticle.Title.IndexOf("africa", StringComparison.OrdinalIgnoreCase) >= 0); - } - } - - [Test] - public void GetPagedItemsFromDelegateResult() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false)); - IQueryBuilder queryBuilder = new QueryBuilder(); - - queryBuilder.Term(BBCFields.Title, "africa"); - DelegateSearchResultFactory articleFactory = new DelegateSearchResultFactory(GetNewsArticleFromDocument); - var results = luceneSearch.Execute, NewsArticle>(queryBuilder, articleFactory.GetItemResult); - var newsArticles = results.GetRange(0, 2); - Assert.Greater(results.TotalHits, newsArticles.Items.Count); - foreach (var newsArticle in newsArticles) - { - Console.WriteLine(newsArticle.Title); - Assert.IsTrue(newsArticle.Title.IndexOf("africa", StringComparison.OrdinalIgnoreCase) >= 0); - } - } - - [Test] - public void GetPagedItemsFromSpecificResult() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false)); - - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Term(BBCFields.Title, "africa"); - var results = luceneSearch.Execute(queryBuilder, x => new NewsArticleItemResult(x)); - var newsArticles = results.GetRange(0, 2); - Assert.Greater(results.TotalHits, newsArticles.Items.Count); - foreach (var newsArticle in newsArticles) - { - Console.WriteLine(newsArticle.Title); - Assert.IsTrue(newsArticle.Title.IndexOf("africa", StringComparison.OrdinalIgnoreCase) >= 0); - } - } - - [Test] - public void TestEnumerable() - { - LuceneSearch luceneSearch = new LuceneSearch(new DirectorySearcherProvider(IndexDirectory, false)); - - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Term(BBCFields.Title, "africa"); - var results = luceneSearch.Execute(queryBuilder, x => new NewsArticleItemResult(x)); - Assert.Greater(results.TotalHits, 0); - foreach (var newsArticle in results) - { - Console.WriteLine(newsArticle.Title); - Assert.IsTrue(newsArticle.Title.IndexOf("africa", StringComparison.OrdinalIgnoreCase) >= 0); - } - } - - #region [ Item Result Tests ] - - [Test] - public void GetItemsFromNewsArticleSearch() - { - NewsArticleSearch newsArticleSearch = new NewsArticleSearch(new DirectorySearcherProvider(IndexDirectory, false)); - - IQueryBuilder queryBuilder = new QueryBuilder(); - queryBuilder.Term(BBCFields.Title, "africa"); - var results = newsArticleSearch.Execute(queryBuilder); - var newsArticles = results.GetRange(0, 2); - Assert.Greater(results.TotalHits, newsArticles.Items.Count); - Assert.Greater(newsArticles.TotalHits, newsArticles.Items.Count); - Assert.Greater(newsArticles.ElapsedTimeMs, 0); - Console.WriteLine("Lucene Search Took {0}ms", results.ElapsedTimeMs); - Console.WriteLine("News Population Took {0}ms", newsArticles.ElapsedTimeMs); - foreach (var newsArticle in newsArticles) - { - Console.WriteLine(newsArticle.Title); - Assert.IsTrue(newsArticle.Title.IndexOf("africa", StringComparison.OrdinalIgnoreCase) >= 0); - } - } - - #endregion - - #region [ Helpers ] - - public static NewsArticle GetNewsArticleFromDocument(Document doc) - { - return Mapper.Map(doc); - } - - public class NewsArticleItemResult : ItemSearchResult - { - public NewsArticleItemResult(ISearchResult nativeSearchResult) : base(nativeSearchResult) - { - } - - public override NewsArticle GetItem(Document document) - { - return GetNewsArticleFromDocument(document); - } - } - - public class NewsArticleSearch : LuceneItemSearch - { - public NewsArticleSearch(string indexPath) : base(indexPath) - { - } - - public NewsArticleSearch(Directory indexDirectory) : base(indexDirectory) - { - } - - public NewsArticleSearch(IIndexSearcherProvider indexSearcherProvider) : base(indexSearcherProvider) - { - } - - protected override NewsArticleItemResult GetItemCreator(ISearchResult searchResult) - { - return new NewsArticleItemResult(searchResult); - } - } - - #endregion - } -} diff --git a/Unit Tests/Lucinq.Solr.UnitTests/packages.config b/Unit Tests/Lucinq.Solr.UnitTests/packages.config index e7f9af6..0be71ad 100644 --- a/Unit Tests/Lucinq.Solr.UnitTests/packages.config +++ b/Unit Tests/Lucinq.Solr.UnitTests/packages.config @@ -1,7 +1,11 @@  - + + + + + \ No newline at end of file diff --git a/Unit Tests/Lucinq.UnitTests/UnitTests/EquivalencyTests.cs b/Unit Tests/Lucinq.UnitTests/UnitTests/EquivalencyTests.cs index d95039e..1c3e7db 100644 --- a/Unit Tests/Lucinq.UnitTests/UnitTests/EquivalencyTests.cs +++ b/Unit Tests/Lucinq.UnitTests/UnitTests/EquivalencyTests.cs @@ -928,7 +928,6 @@ public void OrExtension() x => x.Term("_name", "value2") ); - Assert.AreEqual(builder2, builder); LucinqQueryModel replacementQuery = builder.Build(); LuceneAdapter adapter = new LuceneAdapter(); @@ -995,7 +994,6 @@ public void AndExtension() x => x.Term("_name", "value2") ); - Assert.AreEqual(builder2, builder); LucinqQueryModel replacementQuery = builder.Build(); LuceneAdapter adapter = new LuceneAdapter();