| using J2N.Collections.Generic.Extensions; |
| using Lucene.Net.Documents; |
| using Lucene.Net.Expressions.JS; |
| using Lucene.Net.Index; |
| using Lucene.Net.Search; |
| using Lucene.Net.Store; |
| using Lucene.Net.Support; |
| using Lucene.Net.Util; |
| using NUnit.Framework; |
| using System.Globalization; |
| |
| namespace Lucene.Net.Expressions |
| { |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /// <summary> |
| /// Tests some basic expressions against different queries, |
| /// and fieldcache/docvalues fields against an equivalent sort. |
| /// </summary> |
| /// <remarks> |
| /// Tests some basic expressions against different queries, |
| /// and fieldcache/docvalues fields against an equivalent sort. |
| /// </remarks> |
| [SuppressCodecs("Lucene3x")] |
| public class TestExpressionSorts : LuceneTestCase |
| { |
| private Directory dir; |
| private IndexReader reader; |
| private IndexSearcher searcher; |
| |
| [SetUp] |
| public override void SetUp() |
| { |
| base.SetUp(); |
| dir = NewDirectory(); |
| var iw = new RandomIndexWriter( |
| #if FEATURE_INSTANCE_TESTDATA_INITIALIZATION |
| this, |
| #endif |
| Random, dir); |
| int numDocs = TestUtil.NextInt32(Random, 2049, 4000); |
| for (int i = 0; i < numDocs; i++) |
| { |
| var document = new Document |
| { |
| NewTextField("english", English.Int32ToEnglish(i), Field.Store.NO), |
| NewTextField("oddeven", (i % 2 == 0) ? "even" : "odd", Field.Store.NO), |
| NewStringField("byte", string.Empty + (unchecked((byte) Random.Next())).ToString(CultureInfo.InvariantCulture), Field.Store.NO), |
| NewStringField("short", string.Empty + ((short) Random.Next()).ToString(CultureInfo.InvariantCulture), Field.Store.NO), |
| new Int32Field("int", Random.Next(), Field.Store.NO), |
| new Int64Field("long", Random.NextInt64(), Field.Store.NO), |
| |
| new SingleField("float", Random.NextSingle(), Field.Store.NO), |
| new DoubleField("double", Random.NextDouble(), Field.Store.NO), |
| |
| new NumericDocValuesField("intdocvalues", Random.Next()), |
| new SingleDocValuesField("floatdocvalues", Random.NextSingle()) |
| }; |
| iw.AddDocument(document); |
| } |
| reader = iw.GetReader(); |
| iw.Dispose(); |
| searcher = NewSearcher(reader); |
| } |
| |
| [TearDown] |
| public override void TearDown() |
| { |
| reader.Dispose(); |
| dir.Dispose(); |
| base.TearDown(); |
| } |
| |
| [Test] |
| #if NETFRAMEWORK |
| [AwaitsFix(BugUrl = "https://github.com/apache/lucenenet/issues/269")] // LUCENENET TODO: this test fails on x86 on .NET Framework in Release mode only |
| #endif |
| public virtual void TestQueries() |
| { |
| int n = AtLeast(4); |
| for (int i = 0; i < n; i++) |
| { |
| Filter odd = new QueryWrapperFilter(new TermQuery(new Term("oddeven", "odd"))); |
| AssertQuery(new MatchAllDocsQuery(), null); |
| AssertQuery(new TermQuery(new Term("english", "one")), null); |
| AssertQuery(new MatchAllDocsQuery(), odd); |
| AssertQuery(new TermQuery(new Term("english", "four")), odd); |
| BooleanQuery bq = new BooleanQuery(); |
| bq.Add(new TermQuery(new Term("english", "one")), Occur.SHOULD); |
| bq.Add(new TermQuery(new Term("oddeven", "even")), Occur.SHOULD); |
| AssertQuery(bq, null); |
| // force in order |
| bq.Add(new TermQuery(new Term("english", "two")), Occur.SHOULD); |
| bq.MinimumNumberShouldMatch = 2; |
| AssertQuery(bq, null); |
| } |
| } |
| |
| |
| internal virtual void AssertQuery(Query query, Filter filter) |
| { |
| for (int i = 0; i < 10; i++) |
| { |
| bool reversed = Random.NextBoolean(); |
| SortField[] fields = |
| { |
| new SortField("int", SortFieldType.INT32, reversed), |
| new SortField("long", SortFieldType.INT64, reversed), |
| new SortField("float", SortFieldType.SINGLE, reversed), |
| new SortField("double", SortFieldType.DOUBLE, reversed), |
| new SortField("intdocvalues", SortFieldType.INT32, reversed), |
| new SortField("floatdocvalues", SortFieldType.SINGLE, reversed), |
| new SortField("score", SortFieldType.SCORE) |
| }; |
| fields.Shuffle(Random); |
| int numSorts = TestUtil.NextInt32(Random, 1, fields.Length); |
| AssertQuery(query, filter, new Sort(Arrays.CopyOfRange(fields, 0, numSorts))); |
| } |
| } |
| |
| |
| internal virtual void AssertQuery(Query query, Filter filter, Sort sort) |
| { |
| int size = TestUtil.NextInt32(Random, 1, searcher.IndexReader.MaxDoc / 5); |
| TopDocs expected = searcher.Search(query, filter, size, sort, Random.NextBoolean(), Random.NextBoolean()); |
| |
| // make our actual sort, mutating original by replacing some of the |
| // sortfields with equivalent expressions |
| |
| SortField[] original = sort.GetSort(); |
| SortField[] mutated = new SortField[original.Length]; |
| for (int i = 0; i < mutated.Length; i++) |
| { |
| if (Random.Next(3) > 0) |
| { |
| SortField s = original[i]; |
| Expression expr = JavascriptCompiler.Compile(s.Field); |
| SimpleBindings simpleBindings = new SimpleBindings(); |
| simpleBindings.Add(s); |
| bool reverse = s.Type == SortFieldType.SCORE || s.IsReverse; |
| mutated[i] = expr.GetSortField(simpleBindings, reverse); |
| } |
| else |
| { |
| mutated[i] = original[i]; |
| } |
| } |
| Sort mutatedSort = new Sort(mutated); |
| TopDocs actual = searcher.Search(query, filter, size, mutatedSort, Random.NextBoolean(), Random.NextBoolean()); |
| CheckHits.CheckEqual(query, expected.ScoreDocs, actual.ScoreDocs); |
| if (size < actual.TotalHits) |
| { |
| expected = searcher.SearchAfter(expected.ScoreDocs[size - 1], query, filter, size, sort); |
| actual = searcher.SearchAfter(actual.ScoreDocs[size - 1], query, filter, size, mutatedSort); |
| CheckHits.CheckEqual(query, expected.ScoreDocs, actual.ScoreDocs); |
| } |
| } |
| } |
| } |