From d33c0c11d4c0908131738c1770a5b37e8bcc704a Mon Sep 17 00:00:00 2001 From: Nikolaj Brask-Nielsen Date: Mon, 21 Nov 2022 20:08:14 +0100 Subject: [PATCH] feat: Add DateOnly support to RangeQuery --- .../Search/LuceneSearchQuery.cs | 17 ++ .../Examine.Lucene/Search/FluentApiTests.cs | 149 ++++++++++++++++++ 2 files changed, 166 insertions(+) diff --git a/src/Examine.Lucene/Search/LuceneSearchQuery.cs b/src/Examine.Lucene/Search/LuceneSearchQuery.cs index 0d782a894..57f3cf484 100644 --- a/src/Examine.Lucene/Search/LuceneSearchQuery.cs +++ b/src/Examine.Lucene/Search/LuceneSearchQuery.cs @@ -160,6 +160,23 @@ internal LuceneBooleanOperationBase RangeQueryInternal(string[] fields, T? mi inner.Add(q, Occur.SHOULD); } } +#if !NETSTANDARD2_0 && !NETSTANDARD2_1 + else if(typeof(T) == typeof(DateOnly) && valueType is IIndexRangeValueType dateOnlyType) + { + TimeOnly minValueTime = minInclusive ? TimeOnly.MinValue : TimeOnly.MaxValue; + var minValue = min.HasValue ? (min.Value as DateOnly?)?.ToDateTime(minValueTime) : null; + + TimeOnly maxValueTime = maxInclusive ? TimeOnly.MaxValue : TimeOnly.MinValue; + var maxValue = max.HasValue ? (max.Value as DateOnly?)?.ToDateTime(maxValueTime) : null; + + var q = dateOnlyType.GetQuery(minValue, maxValue, minInclusive, maxInclusive); + + if (q != null) + { + inner.Add(q, Occur.SHOULD); + } + } +#endif else { throw new InvalidOperationException($"Could not perform a range query on the field {f}, it's value type is {valueType?.GetType()}"); diff --git a/src/Examine.Test/Examine.Lucene/Search/FluentApiTests.cs b/src/Examine.Test/Examine.Lucene/Search/FluentApiTests.cs index ebd3d8b0e..8aac33f6f 100644 --- a/src/Examine.Test/Examine.Lucene/Search/FluentApiTests.cs +++ b/src/Examine.Test/Examine.Lucene/Search/FluentApiTests.cs @@ -2555,5 +2555,154 @@ public void Given_SkipTake_Returns_ExpectedTotals(int skip, int take, int expect Assert.AreEqual(expectedResults, results.Count()); } } + +#if NET6_0_OR_GREATER + [Test] + public void Range_DateOnly() + { + var analyzer = new StandardAnalyzer(LuceneInfo.CurrentVersion); + using (var luceneDir = new RandomIdRAMDirectory()) + using (var indexer = GetTestIndex( + luceneDir, + analyzer, + new FieldDefinitionCollection(new FieldDefinition("created", "datetime")))) + { + + + indexer.IndexItems(new[] + { + ValueSet.FromObject(123.ToString(), "content", + new + { + created = new DateTime(2000, 01, 02), + bodyText = "lorem ipsum", + nodeTypeAlias = "CWS_Home" + }), + ValueSet.FromObject(2123.ToString(), "content", + new + { + created = new DateTime(2000, 01, 04), + bodyText = "lorem ipsum", + nodeTypeAlias = "CWS_Test" + }), + ValueSet.FromObject(3123.ToString(), "content", + new + { + created = new DateTime(2000, 01, 05), + bodyText = "lorem ipsum", + nodeTypeAlias = "CWS_Page" + }) + }); + + + var searcher = indexer.Searcher; + + var numberSortedCriteria = searcher.CreateQuery() + .RangeQuery(new[] { "created" }, new DateOnly(2000, 01, 02), new DateOnly(2000, 01, 05), maxInclusive: false); + + var numberSortedResult = numberSortedCriteria.Execute(); + + Assert.AreEqual(2, numberSortedResult.TotalItemCount); + } + } + + [Test] + public void Range_DateOnly_Min_And_Max_Inclusive() + { + var analyzer = new StandardAnalyzer(LuceneInfo.CurrentVersion); + using (var luceneDir = new RandomIdRAMDirectory()) + using (var indexer = GetTestIndex( + luceneDir, + analyzer, + new FieldDefinitionCollection(new FieldDefinition("created", "datetime")))) + { + + + indexer.IndexItems(new[] + { + ValueSet.FromObject(123.ToString(), "content", + new + { + created = new DateTime(2000, 01, 02), + bodyText = "lorem ipsum", + nodeTypeAlias = "CWS_Home" + }), + ValueSet.FromObject(2123.ToString(), "content", + new + { + created = new DateTime(2000, 01, 04), + bodyText = "lorem ipsum", + nodeTypeAlias = "CWS_Test" + }), + ValueSet.FromObject(3123.ToString(), "content", + new + { + created = new DateTime(2000, 01, 05), + bodyText = "lorem ipsum", + nodeTypeAlias = "CWS_Page" + }) + }); + + + var searcher = indexer.Searcher; + + var numberSortedCriteria = searcher.CreateQuery() + .RangeQuery(new[] { "created" }, new DateOnly(2000, 01, 02), new DateOnly(2000, 01, 05)); + + var numberSortedResult = numberSortedCriteria.Execute(); + + Assert.AreEqual(3, numberSortedResult.TotalItemCount); + } + } + + [Test] + public void Range_DateOnly_No_Inclusive() + { + var analyzer = new StandardAnalyzer(LuceneInfo.CurrentVersion); + using (var luceneDir = new RandomIdRAMDirectory()) + using (var indexer = GetTestIndex( + luceneDir, + analyzer, + new FieldDefinitionCollection(new FieldDefinition("created", "datetime")))) + { + + + indexer.IndexItems(new[] + { + ValueSet.FromObject(123.ToString(), "content", + new + { + created = new DateTime(2000, 01, 02), + bodyText = "lorem ipsum", + nodeTypeAlias = "CWS_Home" + }), + ValueSet.FromObject(2123.ToString(), "content", + new + { + created = new DateTime(2000, 01, 04), + bodyText = "lorem ipsum", + nodeTypeAlias = "CWS_Test" + }), + ValueSet.FromObject(3123.ToString(), "content", + new + { + created = new DateTime(2000, 01, 05), + bodyText = "lorem ipsum", + nodeTypeAlias = "CWS_Page" + }) + }); + + + var searcher = indexer.Searcher; + + var numberSortedCriteria = searcher.CreateQuery() + .RangeQuery(new[] { "created" }, new DateOnly(2000, 01, 02), new DateOnly(2000, 01, 05), minInclusive: false, maxInclusive: false); + + var numberSortedResult = numberSortedCriteria.Execute(); + + Assert.AreEqual(1, numberSortedResult.TotalItemCount); + } + } +#endif } }