Skip to content

Commit

Permalink
add test
Browse files Browse the repository at this point in the history
Signed-off-by: panguixin <[email protected]>
  • Loading branch information
bugmakerrrrrr committed Jul 22, 2024
1 parent b8bbcc7 commit 47f5073
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -785,61 +785,3 @@
- match: { hits.hits.2._index: test }
- match: { hits.hits.2._source.unsignedlong: null }
- match: { hits.hits.2._source.id: 22 }

---
"search with null search after value":
- do:
indices.create:
index: test
body:
mappings:
properties:
doc:
type: keyword
name:
type: keyword

- do:
bulk:
refresh: true
index: test
body: |
{"index":{}}
{ "doc": "doc1", "name": "bob"}
{"index":{}}
{ "doc": "doc2", "name": null}
{"index":{}}
{ "doc": "doc3", "name": null}
- do:
search:
rest_total_hits_as_int: true
index: test
body:
size: 2
track_total_hits: false
sort: [{ name: desc }, { doc: desc }]

- match: {hits.total: -1 }
- length: {hits.hits: 2 }
- match: {hits.hits.0._index: test }
- match: {hits.hits.0._source.doc: doc1 }
- match: {hits.hits.1._index: test }
- match: {hits.hits.1._source.doc: doc3 }
- match: {hits.hits.1.sort: [null, "doc3"] }

- do:
search:
rest_total_hits_as_int: true
index: test
body:
size: 1
track_total_hits: false
sort: [{ name: desc }, { doc: desc }]
search_after: [null, "doc3"]

- match: {hits.total: -1 }
- length: {hits.hits: 1 }
- match: {hits.hits.0._index: test }
- match: {hits.hits.0._source.doc: doc2 }
- match: {hits.hits.0.sort: [null, "doc2"] }
159 changes: 159 additions & 0 deletions server/src/test/java/org/opensearch/search/SearchServiceTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.apache.lucene.store.AlreadyClosedException;
import org.opensearch.OpenSearchException;
import org.opensearch.action.OriginalIndices;
import org.opensearch.action.bulk.BulkRequestBuilder;
import org.opensearch.action.index.IndexResponse;
import org.opensearch.action.search.ClearScrollRequest;
import org.opensearch.action.search.DeletePitResponse;
Expand All @@ -56,10 +57,13 @@
import org.opensearch.action.support.IndicesOptions;
import org.opensearch.action.support.PlainActionFuture;
import org.opensearch.action.support.WriteRequest;
import org.opensearch.common.CheckedTriFunction;
import org.opensearch.common.Numbers;
import org.opensearch.common.UUIDs;
import org.opensearch.common.settings.Settings;
import org.opensearch.common.settings.SettingsException;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.common.xcontent.XContentFactory;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.common.Strings;
import org.opensearch.core.common.io.stream.StreamInput;
Expand All @@ -68,13 +72,16 @@
import org.opensearch.core.index.Index;
import org.opensearch.core.index.shard.ShardId;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.core.xcontent.MediaTypeRegistry;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.index.IndexModule;
import org.opensearch.index.IndexNotFoundException;
import org.opensearch.index.IndexService;
import org.opensearch.index.IndexSettings;
import org.opensearch.index.engine.Engine;
import org.opensearch.index.mapper.DerivedFieldType;
import org.opensearch.index.mapper.MapperService;
import org.opensearch.index.mapper.NumberFieldMapper;
import org.opensearch.index.query.AbstractQueryBuilder;
import org.opensearch.index.query.MatchAllQueryBuilder;
import org.opensearch.index.query.MatchNoneQueryBuilder;
Expand Down Expand Up @@ -110,13 +117,17 @@
import org.opensearch.search.query.QuerySearchResult;
import org.opensearch.search.sort.MinAndMax;
import org.opensearch.search.sort.SortAndFormats;
import org.opensearch.search.sort.SortBuilders;
import org.opensearch.search.sort.SortOrder;
import org.opensearch.search.suggest.SuggestBuilder;
import org.opensearch.test.OpenSearchSingleNodeTestCase;
import org.opensearch.threadpool.ThreadPool;
import org.junit.Before;

import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
Expand Down Expand Up @@ -1170,6 +1181,154 @@ public void testCanRewriteToMatchNone() {
);
}

private Number randomNumber(NumberFieldMapper.NumberType type) {
switch (type) {
case BYTE:
return randomByte();
case SHORT:
return randomShort();
case INTEGER:
return randomInt(10000);
case LONG:
return randomLongBetween(0L, 10000L);
case DOUBLE:
return randomDoubleBetween(0, 10000, false);
case FLOAT:
case HALF_FLOAT:
return (float) randomDoubleBetween(0, 10000, false);
case UNSIGNED_LONG:
BigInteger ul = randomUnsignedLong();
while (ul.compareTo(Numbers.MIN_UNSIGNED_LONG_VALUE) == 0 || ul.compareTo(Numbers.MAX_UNSIGNED_LONG_VALUE) == 0) {
ul = randomUnsignedLong();
}
return ul;
default:
throw new AssertionError();
}
}

private Number incDecNumber(Number number, NumberFieldMapper.NumberType type, boolean inc) {
switch (type) {
case BYTE:
case SHORT:
case INTEGER:
return number.intValue() + (inc ? 1 : -1);
case LONG:
return number.longValue() + (inc ? 1 : -1);
case DOUBLE:
return number.doubleValue() + (inc ? 1 : -1);
case FLOAT:
case HALF_FLOAT:
return number.floatValue() + (inc ? 1 : -1);
case UNSIGNED_LONG:
return ((BigInteger) number).add(inc ? BigInteger.valueOf(1) : BigInteger.valueOf(-1));
default:
throw new AssertionError();
}
}

private void canMatchSearchAfterNumericTestCase(NumberFieldMapper.NumberType type) throws Exception {
XContentBuilder mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("properties")
.startObject("num1")
.field("type", type.typeName())
.endObject()
.startObject("num2")
.field("type", type.typeName())
.endObject()
.endObject()
.endObject();
IndexService indexService = createIndex("test", Settings.EMPTY, MapperService.SINGLE_MAPPING_NAME, mapping);
ensureGreen();

final BulkRequestBuilder bulkRequestBuilder = client().prepareBulk();
final int numDocs = randomIntBetween(10, 20);
final Number[] nums1 = new Number[numDocs];
final Number[] nums2 = new Number[numDocs];
for (int i = 0; i < numDocs; i++) {
nums1[i] = randomNumber(type);
nums2[i] = randomNumber(type);
bulkRequestBuilder.add(
client().prepareIndex("test")
.setId(String.valueOf(i))
.setSource(String.format(Locale.ROOT, "{\"num1\": %s, \"num2\": %s}", nums1[i].toString(), nums2[i].toString()), MediaTypeRegistry.JSON)
);
}
bulkRequestBuilder.get();
client().admin().indices().prepareRefresh().get();
Arrays.sort(nums1);
Arrays.sort(nums2);

final IndexShard shard = indexService.getShard(0);
final SearchService service = getInstanceFromNode(SearchService.class);
final ShardSearchRequest shardRequest = new ShardSearchRequest(
OriginalIndices.NONE,
new SearchRequest().allowPartialSearchResults(true),
shard.shardId(),
1,
new AliasFilter(null, Strings.EMPTY_ARRAY),
1f,
-1,
null,
null
);
assertFalse(shard.hasRefreshPending());

final CheckedTriFunction<Boolean, Boolean, Boolean, Void, Exception> outOfRangeTester = (outOfRange, missingMatch, reverse) -> {
Number searchAfter;
Object missing;
if (outOfRange) {
searchAfter = reverse ? incDecNumber(nums1[0], type, false) : incDecNumber(nums1[numDocs - 1], type, true);
} else {
searchAfter = randomFrom(nums1);
}
if (missingMatch) {
missing = reverse ? (randomBoolean() ? "_last" : incDecNumber(searchAfter, type, false)) : (randomBoolean() ? "_last" : incDecNumber(searchAfter, type, true));
} else {
missing = reverse ? (randomBoolean() ? "_first" : incDecNumber(searchAfter, type, true)) : (randomBoolean() ? "_first" : incDecNumber(searchAfter, type, false));
}
shardRequest.source(new SearchSourceBuilder().query(new MatchAllQueryBuilder()).trackTotalHits(false));
shardRequest.source()
.sort(SortBuilders.fieldSort("num1").missing(missing).order(reverse ? SortOrder.DESC : SortOrder.ASC));
List<Object> searchAfterFields = new ArrayList<>();
searchAfterFields.add(searchAfter);
if (randomBoolean()) {
shardRequest.source().sort("num2");
searchAfterFields.add(randomFrom(nums2));
}
shardRequest.source().searchAfter(searchAfterFields.toArray());
SearchService.CanMatchResponse response = service.canMatch(shardRequest);

if (type == NumberFieldMapper.NumberType.HALF_FLOAT || type == NumberFieldMapper.NumberType.UNSIGNED_LONG) {
assertTrue(response.canMatch());
return null;
}

if (outOfRange == false || missingMatch) {
assertTrue(response.canMatch());
} else {
assertFalse(response.canMatch());
}
return null;
};
for (boolean outOfRange : new boolean[] { true, false }) {
for (boolean missingMatch : new boolean[] { true, false }) {
for (boolean reverse : new boolean[] { true, false }) {
outOfRangeTester.apply(outOfRange, missingMatch, reverse);
}
}
}
client().admin().indices().prepareDelete("test").get();
ensureGreen();
}

public void testNumericCanMatch() throws Exception {
for (var type: NumberFieldMapper.NumberType.values()) {
canMatchSearchAfterNumericTestCase(type);
}
}

public void testSetSearchThrottled() {
createIndex("throttled_threadpool_index");
client().execute(
Expand Down

0 comments on commit 47f5073

Please sign in to comment.