mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-12 07:55:24 +00:00
Supporting sort modes avg
and sum
when sorting inside nested objects.
Previously this commit either sort modes `min` or `max` (depending on sort order) was used when sort modes `avg` and `sum` were picked. Closes #2701
This commit is contained in:
parent
39f362326e
commit
d99b532f0f
@ -56,4 +56,14 @@ public final class ByteValuesComparator extends LongValuesComparatorBase<Byte> {
|
|||||||
public Byte value(int slot) {
|
public Byte value(int slot) {
|
||||||
return Byte.valueOf(values[slot]);
|
return Byte.valueOf(values[slot]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(int slot, int doc) {
|
||||||
|
values[slot] += (byte) readerValues.getValueMissing(doc, missingValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void divide(int slot, int divisor) {
|
||||||
|
values[slot] /= divisor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,4 +56,14 @@ public final class DoubleValuesComparator extends DoubleValuesComparatorBase<Dou
|
|||||||
public Double value(int slot) {
|
public Double value(int slot) {
|
||||||
return Double.valueOf(values[slot]);
|
return Double.valueOf(values[slot]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(int slot, int doc) {
|
||||||
|
values[slot] += readerValues.getValueMissing(doc, missingValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void divide(int slot, int divisor) {
|
||||||
|
values[slot] /= divisor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
abstract class DoubleValuesComparatorBase<T extends Number> extends FieldComparator<T> {
|
abstract class DoubleValuesComparatorBase<T extends Number> extends NumberComparatorBase<T> {
|
||||||
|
|
||||||
protected final IndexNumericFieldData<?> indexFieldData;
|
protected final IndexNumericFieldData<?> indexFieldData;
|
||||||
protected final double missingValue;
|
protected final double missingValue;
|
||||||
|
@ -63,4 +63,13 @@ public final class FloatValuesComparator extends DoubleValuesComparatorBase<Floa
|
|||||||
return Float.valueOf(values[slot]);
|
return Float.valueOf(values[slot]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(int slot, int doc) {
|
||||||
|
values[slot] += (float) readerValues.getValueMissing(doc, missingValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void divide(int slot, int divisor) {
|
||||||
|
values[slot] /= divisor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,4 +62,14 @@ public final class IntValuesComparator extends LongValuesComparatorBase<Integer>
|
|||||||
public Integer value(int slot) {
|
public Integer value(int slot) {
|
||||||
return Integer.valueOf(values[slot]);
|
return Integer.valueOf(values[slot]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(int slot, int doc) {
|
||||||
|
values[slot] += (int) readerValues.getValueMissing(doc, missingValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void divide(int slot, int divisor) {
|
||||||
|
values[slot] /= divisor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,4 +55,14 @@ public final class LongValuesComparator extends LongValuesComparatorBase<Long> {
|
|||||||
public Long value(int slot) {
|
public Long value(int slot) {
|
||||||
return Long.valueOf(values[slot]);
|
return Long.valueOf(values[slot]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(int slot, int doc) {
|
||||||
|
values[slot] += readerValues.getValueMissing(doc, missingValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void divide(int slot, int divisor) {
|
||||||
|
values[slot] /= divisor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import org.elasticsearch.index.fielddata.LongValues;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
abstract class LongValuesComparatorBase<T extends Number> extends FieldComparator<T> {
|
abstract class LongValuesComparatorBase<T extends Number> extends NumberComparatorBase<T> {
|
||||||
|
|
||||||
protected final IndexNumericFieldData<?> indexFieldData;
|
protected final IndexNumericFieldData<?> indexFieldData;
|
||||||
protected final long missingValue;
|
protected final long missingValue;
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.index.fielddata.fieldcomparator;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.FieldComparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base FieldComparator class for number fields.
|
||||||
|
*/
|
||||||
|
// This is right now only used for sorting number based fields inside nested objects
|
||||||
|
public abstract class NumberComparatorBase<T> extends FieldComparator<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds numeric value at the specified doc to the specified slot.
|
||||||
|
*
|
||||||
|
* @param slot The specified slot
|
||||||
|
* @param doc The specified doc
|
||||||
|
*/
|
||||||
|
public abstract void add(int slot, int doc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divides the value at the specified slot with the specified divisor.
|
||||||
|
*
|
||||||
|
* @param slot The specified slot
|
||||||
|
* @param divisor The specified divisor
|
||||||
|
*/
|
||||||
|
public abstract void divide(int slot, int divisor);
|
||||||
|
}
|
@ -59,4 +59,13 @@ public final class ShortValuesComparator extends LongValuesComparatorBase<Short>
|
|||||||
return Short.valueOf(values[slot]);
|
return Short.valueOf(values[slot]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(int slot, int doc) {
|
||||||
|
values[slot] += (short) readerValues.getValueMissing(doc, missingValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void divide(int slot, int divisor) {
|
||||||
|
values[slot] /= divisor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch 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.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.elasticsearch.index.search.nested;
|
package org.elasticsearch.index.search.nested;
|
||||||
|
|
||||||
import org.apache.lucene.index.AtomicReaderContext;
|
import org.apache.lucene.index.AtomicReaderContext;
|
||||||
@ -9,6 +28,7 @@ import org.apache.lucene.util.FixedBitSet;
|
|||||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||||
import org.elasticsearch.common.lucene.docset.DocIdSets;
|
import org.elasticsearch.common.lucene.docset.DocIdSets;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.NumberComparatorBase;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -38,6 +58,10 @@ public class NestedFieldComparatorSource extends IndexFieldData.XFieldComparator
|
|||||||
return new NestedFieldComparator.Highest(wrappedComparator, rootDocumentsFilter, innerDocumentsFilter, numHits);
|
return new NestedFieldComparator.Highest(wrappedComparator, rootDocumentsFilter, innerDocumentsFilter, numHits);
|
||||||
case MIN:
|
case MIN:
|
||||||
return new NestedFieldComparator.Lowest(wrappedComparator, rootDocumentsFilter, innerDocumentsFilter, numHits);
|
return new NestedFieldComparator.Lowest(wrappedComparator, rootDocumentsFilter, innerDocumentsFilter, numHits);
|
||||||
|
case SUM:
|
||||||
|
return new Sum((NumberComparatorBase) wrappedComparator, rootDocumentsFilter, innerDocumentsFilter, numHits);
|
||||||
|
case AVG:
|
||||||
|
return new Avg((NumberComparatorBase) wrappedComparator, rootDocumentsFilter, innerDocumentsFilter, numHits);
|
||||||
default:
|
default:
|
||||||
throw new ElasticSearchIllegalArgumentException(
|
throw new ElasticSearchIllegalArgumentException(
|
||||||
String.format("Unsupported sort_mode[%s] for nested type", sortMode)
|
String.format("Unsupported sort_mode[%s] for nested type", sortMode)
|
||||||
@ -51,6 +75,165 @@ public class NestedFieldComparatorSource extends IndexFieldData.XFieldComparator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Sum extends FieldComparator {
|
||||||
|
|
||||||
|
final Filter rootDocumentsFilter;
|
||||||
|
final Filter innerDocumentsFilter;
|
||||||
|
final int spareSlot;
|
||||||
|
|
||||||
|
NumberComparatorBase wrappedComparator;
|
||||||
|
FixedBitSet rootDocuments;
|
||||||
|
FixedBitSet innerDocuments;
|
||||||
|
int bottomSlot;
|
||||||
|
|
||||||
|
Sum(NumberComparatorBase wrappedComparator, Filter rootDocumentsFilter, Filter innerDocumentsFilter, int spareSlot) {
|
||||||
|
this.wrappedComparator = wrappedComparator;
|
||||||
|
this.rootDocumentsFilter = rootDocumentsFilter;
|
||||||
|
this.innerDocumentsFilter = innerDocumentsFilter;
|
||||||
|
this.spareSlot = spareSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(int slot1, int slot2) {
|
||||||
|
return wrappedComparator.compare(slot1, slot2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBottom(int slot) {
|
||||||
|
wrappedComparator.setBottom(slot);
|
||||||
|
this.bottomSlot = slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
|
||||||
|
DocIdSet innerDocuments = innerDocumentsFilter.getDocIdSet(context, null);
|
||||||
|
if (DocIdSets.isEmpty(innerDocuments)) {
|
||||||
|
this.innerDocuments = null;
|
||||||
|
} else if (innerDocuments instanceof FixedBitSet) {
|
||||||
|
this.innerDocuments = (FixedBitSet) innerDocuments;
|
||||||
|
} else {
|
||||||
|
this.innerDocuments = DocIdSets.toFixedBitSet(innerDocuments.iterator(), context.reader().maxDoc());
|
||||||
|
}
|
||||||
|
DocIdSet rootDocuments = rootDocumentsFilter.getDocIdSet(context, null);
|
||||||
|
if (DocIdSets.isEmpty(rootDocuments)) {
|
||||||
|
this.rootDocuments = null;
|
||||||
|
} else if (rootDocuments instanceof FixedBitSet) {
|
||||||
|
this.rootDocuments = (FixedBitSet) rootDocuments;
|
||||||
|
} else {
|
||||||
|
this.rootDocuments = DocIdSets.toFixedBitSet(rootDocuments.iterator(), context.reader().maxDoc());
|
||||||
|
}
|
||||||
|
|
||||||
|
wrappedComparator = (NumberComparatorBase) wrappedComparator.setNextReader(context);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object value(int slot) {
|
||||||
|
return wrappedComparator.value(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareBottom(int rootDoc) throws IOException {
|
||||||
|
if (rootDoc == 0 || rootDocuments == null || innerDocuments == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prevRootDoc = rootDocuments.prevSetBit(rootDoc - 1);
|
||||||
|
int nestedDoc = innerDocuments.nextSetBit(prevRootDoc + 1);
|
||||||
|
if (nestedDoc >= rootDoc || nestedDoc == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wrappedComparator.copy(spareSlot, nestedDoc);
|
||||||
|
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
|
||||||
|
while (nestedDoc > prevRootDoc && nestedDoc < rootDoc) {
|
||||||
|
wrappedComparator.add(spareSlot, nestedDoc);
|
||||||
|
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
|
||||||
|
}
|
||||||
|
return compare(bottomSlot, spareSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void copy(int slot, int rootDoc) throws IOException {
|
||||||
|
if (rootDoc == 0 || rootDocuments == null || innerDocuments == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prevRootDoc = rootDocuments.prevSetBit(rootDoc - 1);
|
||||||
|
int nestedDoc = innerDocuments.nextSetBit(prevRootDoc + 1);
|
||||||
|
if (nestedDoc >= rootDoc || nestedDoc == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wrappedComparator.copy(slot, nestedDoc);
|
||||||
|
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
|
||||||
|
while (nestedDoc > prevRootDoc && nestedDoc < rootDoc) {
|
||||||
|
wrappedComparator.add(slot, nestedDoc);
|
||||||
|
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareDocToValue(int rootDoc, Object value) throws IOException {
|
||||||
|
throw new UnsupportedOperationException("compareDocToValue() not used for sorting in ES");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class Avg extends Sum {
|
||||||
|
|
||||||
|
Avg(NumberComparatorBase wrappedComparator, Filter rootDocumentsFilter, Filter innerDocumentsFilter, int spareSlot) {
|
||||||
|
super(wrappedComparator, rootDocumentsFilter, innerDocumentsFilter, spareSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareBottom(int rootDoc) throws IOException {
|
||||||
|
if (rootDoc == 0 || rootDocuments == null || innerDocuments == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prevRootDoc = rootDocuments.prevSetBit(rootDoc - 1);
|
||||||
|
int nestedDoc = innerDocuments.nextSetBit(prevRootDoc + 1);
|
||||||
|
if (nestedDoc >= rootDoc || nestedDoc == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int counter = 1;
|
||||||
|
wrappedComparator.copy(spareSlot, nestedDoc);
|
||||||
|
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
|
||||||
|
while (nestedDoc > prevRootDoc && nestedDoc < rootDoc) {
|
||||||
|
wrappedComparator.add(spareSlot, nestedDoc);
|
||||||
|
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
wrappedComparator.divide(spareSlot, counter);
|
||||||
|
return compare(bottomSlot, spareSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void copy(int slot, int rootDoc) throws IOException {
|
||||||
|
if (rootDoc == 0 || rootDocuments == null || innerDocuments == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prevRootDoc = rootDocuments.prevSetBit(rootDoc - 1);
|
||||||
|
int nestedDoc = innerDocuments.nextSetBit(prevRootDoc + 1);
|
||||||
|
if (nestedDoc >= rootDoc || nestedDoc == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int counter = 1;
|
||||||
|
wrappedComparator.copy(slot, nestedDoc);
|
||||||
|
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
|
||||||
|
while (nestedDoc > prevRootDoc && nestedDoc < rootDoc) {
|
||||||
|
wrappedComparator.add(slot, nestedDoc);
|
||||||
|
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
wrappedComparator.divide(slot, counter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to Lucene join module
|
||||||
abstract class NestedFieldComparator extends FieldComparator {
|
abstract class NestedFieldComparator extends FieldComparator {
|
||||||
|
|
||||||
final Filter rootDocumentsFilter;
|
final Filter rootDocumentsFilter;
|
||||||
|
@ -224,10 +224,6 @@ public class SortParseElement implements SearchParseElement {
|
|||||||
} else {
|
} else {
|
||||||
innerDocumentsFilter = context.filterCache().cache(objectMapper.nestedTypeFilter());
|
innerDocumentsFilter = context.filterCache().cache(objectMapper.nestedTypeFilter());
|
||||||
}
|
}
|
||||||
// For now the nested sorting doesn't support SUM or AVG
|
|
||||||
if (sortMode == SortMode.SUM || sortMode == SortMode.AVG) {
|
|
||||||
sortMode = resolveDefaultSortMode(reverse);
|
|
||||||
}
|
|
||||||
fieldComparatorSource = new NestedFieldComparatorSource(sortMode, fieldComparatorSource, rootDocumentsFilter, innerDocumentsFilter);
|
fieldComparatorSource = new NestedFieldComparatorSource(sortMode, fieldComparatorSource, rootDocumentsFilter, innerDocumentsFilter);
|
||||||
}
|
}
|
||||||
sortFields.add(new SortField(fieldMapper.names().indexName(), fieldComparatorSource, reverse));
|
sortFields.add(new SortField(fieldMapper.names().indexName(), fieldComparatorSource, reverse));
|
||||||
|
@ -706,6 +706,7 @@ public class SimpleNestedTests extends AbstractNodesTests {
|
|||||||
.execute().actionGet();
|
.execute().actionGet();
|
||||||
client.admin().cluster().prepareHealth().setWaitForGreenStatus().execute().actionGet();
|
client.admin().cluster().prepareHealth().setWaitForGreenStatus().execute().actionGet();
|
||||||
|
|
||||||
|
// sum: 11
|
||||||
client.prepareIndex("test", "type1", Integer.toString(1)).setSource(jsonBuilder().startObject()
|
client.prepareIndex("test", "type1", Integer.toString(1)).setSource(jsonBuilder().startObject()
|
||||||
.field("grand_parent_values", 1l)
|
.field("grand_parent_values", 1l)
|
||||||
.startObject("parent")
|
.startObject("parent")
|
||||||
@ -737,6 +738,7 @@ public class SimpleNestedTests extends AbstractNodesTests {
|
|||||||
.endObject()
|
.endObject()
|
||||||
.endObject()).execute().actionGet();
|
.endObject()).execute().actionGet();
|
||||||
|
|
||||||
|
// sum: 7
|
||||||
client.prepareIndex("test", "type1", Integer.toString(2)).setSource(jsonBuilder().startObject()
|
client.prepareIndex("test", "type1", Integer.toString(2)).setSource(jsonBuilder().startObject()
|
||||||
.field("grand_parent_values", 2l)
|
.field("grand_parent_values", 2l)
|
||||||
.startObject("parent")
|
.startObject("parent")
|
||||||
@ -768,6 +770,7 @@ public class SimpleNestedTests extends AbstractNodesTests {
|
|||||||
.endObject()
|
.endObject()
|
||||||
.endObject()).execute().actionGet();
|
.endObject()).execute().actionGet();
|
||||||
|
|
||||||
|
// sum: 2
|
||||||
client.prepareIndex("test", "type1", Integer.toString(3)).setSource(jsonBuilder().startObject()
|
client.prepareIndex("test", "type1", Integer.toString(3)).setSource(jsonBuilder().startObject()
|
||||||
.field("grand_parent_values", 3l)
|
.field("grand_parent_values", 3l)
|
||||||
.startObject("parent")
|
.startObject("parent")
|
||||||
@ -911,6 +914,121 @@ public class SimpleNestedTests extends AbstractNodesTests {
|
|||||||
assertThat(searchResponse.getHits().getHits()[1].sortValues()[0].toString(), equalTo("2"));
|
assertThat(searchResponse.getHits().getHits()[1].sortValues()[0].toString(), equalTo("2"));
|
||||||
assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
|
assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
|
||||||
assertThat(searchResponse.getHits().getHits()[2].sortValues()[0].toString(), equalTo("3"));
|
assertThat(searchResponse.getHits().getHits()[2].sortValues()[0].toString(), equalTo("3"));
|
||||||
|
|
||||||
|
// Sort mode: sum
|
||||||
|
searchResponse = client.prepareSearch()
|
||||||
|
.setQuery(matchAllQuery())
|
||||||
|
.addSort(
|
||||||
|
SortBuilders.fieldSort("parent.child.child_values")
|
||||||
|
.setNestedPath("parent.child")
|
||||||
|
.sortMode("sum")
|
||||||
|
.order(SortOrder.ASC)
|
||||||
|
)
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(searchResponse.getHits().totalHits(), equalTo(3l));
|
||||||
|
assertThat(searchResponse.getHits().getHits().length, equalTo(3));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("3"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[0].sortValues()[0].toString(), equalTo("2"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[1].sortValues()[0].toString(), equalTo("7"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("1"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[2].sortValues()[0].toString(), equalTo("11"));
|
||||||
|
|
||||||
|
|
||||||
|
searchResponse = client.prepareSearch()
|
||||||
|
.setQuery(matchAllQuery())
|
||||||
|
.addSort(
|
||||||
|
SortBuilders.fieldSort("parent.child.child_values")
|
||||||
|
.setNestedPath("parent.child")
|
||||||
|
.sortMode("sum")
|
||||||
|
.order(SortOrder.DESC)
|
||||||
|
)
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(searchResponse.getHits().totalHits(), equalTo(3l));
|
||||||
|
assertThat(searchResponse.getHits().getHits().length, equalTo(3));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[0].sortValues()[0].toString(), equalTo("11"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[1].sortValues()[0].toString(), equalTo("7"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[2].sortValues()[0].toString(), equalTo("2"));
|
||||||
|
|
||||||
|
// Sort mode: sum with filter
|
||||||
|
searchResponse = client.prepareSearch()
|
||||||
|
.setQuery(matchAllQuery())
|
||||||
|
.addSort(
|
||||||
|
SortBuilders.fieldSort("parent.child.child_values")
|
||||||
|
.setNestedPath("parent.child")
|
||||||
|
.setNestedFilter(FilterBuilders.termFilter("parent.child.filter", true))
|
||||||
|
.sortMode("sum")
|
||||||
|
.order(SortOrder.ASC)
|
||||||
|
)
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(searchResponse.getHits().totalHits(), equalTo(3l));
|
||||||
|
assertThat(searchResponse.getHits().getHits().length, equalTo(3));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[0].sortValues()[0].toString(), equalTo("1"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[1].sortValues()[0].toString(), equalTo("2"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[2].sortValues()[0].toString(), equalTo("3"));
|
||||||
|
|
||||||
|
// Sort mode: avg
|
||||||
|
searchResponse = client.prepareSearch()
|
||||||
|
.setQuery(matchAllQuery())
|
||||||
|
.addSort(
|
||||||
|
SortBuilders.fieldSort("parent.child.child_values")
|
||||||
|
.setNestedPath("parent.child")
|
||||||
|
.sortMode("avg")
|
||||||
|
.order(SortOrder.ASC)
|
||||||
|
)
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(searchResponse.getHits().totalHits(), equalTo(3l));
|
||||||
|
assertThat(searchResponse.getHits().getHits().length, equalTo(3));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("3"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[0].sortValues()[0].toString(), equalTo("0"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[1].sortValues()[0].toString(), equalTo("1"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("1"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[2].sortValues()[0].toString(), equalTo("2"));
|
||||||
|
|
||||||
|
searchResponse = client.prepareSearch()
|
||||||
|
.setQuery(matchAllQuery())
|
||||||
|
.addSort(
|
||||||
|
SortBuilders.fieldSort("parent.child.child_values")
|
||||||
|
.setNestedPath("parent.child")
|
||||||
|
.sortMode("avg")
|
||||||
|
.order(SortOrder.DESC)
|
||||||
|
)
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(searchResponse.getHits().totalHits(), equalTo(3l));
|
||||||
|
assertThat(searchResponse.getHits().getHits().length, equalTo(3));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[0].sortValues()[0].toString(), equalTo("2"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[1].sortValues()[0].toString(), equalTo("1"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[2].sortValues()[0].toString(), equalTo("0"));
|
||||||
|
|
||||||
|
// Sort mode: avg with filter
|
||||||
|
searchResponse = client.prepareSearch()
|
||||||
|
.setQuery(matchAllQuery())
|
||||||
|
.addSort(
|
||||||
|
SortBuilders.fieldSort("parent.child.child_values")
|
||||||
|
.setNestedPath("parent.child")
|
||||||
|
.setNestedFilter(FilterBuilders.termFilter("parent.child.filter", true))
|
||||||
|
.sortMode("avg")
|
||||||
|
.order(SortOrder.ASC)
|
||||||
|
)
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(searchResponse.getHits().totalHits(), equalTo(3l));
|
||||||
|
assertThat(searchResponse.getHits().getHits().length, equalTo(3));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[0].sortValues()[0].toString(), equalTo("1"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("2"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[1].sortValues()[0].toString(), equalTo("2"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("3"));
|
||||||
|
assertThat(searchResponse.getHits().getHits()[2].sortValues()[0].toString(), equalTo("3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,314 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.test.unit.index.search.nested;
|
||||||
|
|
||||||
|
import org.apache.lucene.document.Document;
|
||||||
|
import org.apache.lucene.document.Field;
|
||||||
|
import org.apache.lucene.document.StringField;
|
||||||
|
import org.apache.lucene.index.DirectoryReader;
|
||||||
|
import org.apache.lucene.index.IndexableField;
|
||||||
|
import org.apache.lucene.index.Term;
|
||||||
|
import org.apache.lucene.search.*;
|
||||||
|
import org.apache.lucene.search.join.ScoreMode;
|
||||||
|
import org.apache.lucene.search.join.ToParentBlockJoinQuery;
|
||||||
|
import org.elasticsearch.common.lucene.search.AndFilter;
|
||||||
|
import org.elasticsearch.common.lucene.search.NotFilter;
|
||||||
|
import org.elasticsearch.common.lucene.search.TermFilter;
|
||||||
|
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||||
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
|
import org.elasticsearch.index.search.nested.NestedFieldComparatorSource;
|
||||||
|
import org.elasticsearch.test.unit.index.fielddata.AbstractFieldDataTests;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public abstract class AbstractNumberNestedSortingTests extends AbstractFieldDataTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNestedSorting() throws Exception {
|
||||||
|
List<Document> docs = new ArrayList<Document>();
|
||||||
|
Document document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(new StringField("__type", "parent", Field.Store.NO));
|
||||||
|
document.add(createField("field1", 1, Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
writer.addDocuments(docs);
|
||||||
|
writer.commit();
|
||||||
|
|
||||||
|
docs.clear();
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 2, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(new StringField("__type", "parent", Field.Store.NO));
|
||||||
|
document.add(createField("field1", 2, Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
writer.addDocuments(docs);
|
||||||
|
|
||||||
|
docs.clear();
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 1, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(new StringField("__type", "parent", Field.Store.NO));
|
||||||
|
document.add(createField("field1", 3, Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
writer.addDocuments(docs);
|
||||||
|
|
||||||
|
docs.clear();
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "F", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 4, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "F", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(new StringField("__type", "parent", Field.Store.NO));
|
||||||
|
document.add(createField("field1", 4, Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
writer.addDocuments(docs);
|
||||||
|
writer.commit();
|
||||||
|
|
||||||
|
docs.clear();
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "F", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "F", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 5, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "F", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(new StringField("__type", "parent", Field.Store.NO));
|
||||||
|
document.add(createField("field1", 5, Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
writer.addDocuments(docs);
|
||||||
|
|
||||||
|
docs.clear();
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 6, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(new StringField("__type", "parent", Field.Store.NO));
|
||||||
|
document.add(createField("field1", 6, Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
writer.addDocuments(docs);
|
||||||
|
|
||||||
|
// This doc will not be included, because it doesn't have nested docs
|
||||||
|
document = new Document();
|
||||||
|
document.add(new StringField("__type", "parent", Field.Store.NO));
|
||||||
|
document.add(createField("field1", 7, Field.Store.NO));
|
||||||
|
writer.addDocument(document);
|
||||||
|
|
||||||
|
docs.clear();
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "T", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 3, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "F", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(createField("field2", 7, Field.Store.NO));
|
||||||
|
document.add(new StringField("filter_1", "F", Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(new StringField("__type", "parent", Field.Store.NO));
|
||||||
|
document.add(createField("field1", 8, Field.Store.NO));
|
||||||
|
docs.add(document);
|
||||||
|
writer.addDocuments(docs);
|
||||||
|
writer.commit();
|
||||||
|
|
||||||
|
// Some garbage docs, just to check if the NestedFieldComparator can deal with this.
|
||||||
|
document = new Document();
|
||||||
|
document.add(new StringField("fieldXXX", "x", Field.Store.NO));
|
||||||
|
writer.addDocument(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(new StringField("fieldXXX", "x", Field.Store.NO));
|
||||||
|
writer.addDocument(document);
|
||||||
|
document = new Document();
|
||||||
|
document.add(new StringField("fieldXXX", "x", Field.Store.NO));
|
||||||
|
writer.addDocument(document);
|
||||||
|
|
||||||
|
SortMode sortMode = SortMode.SUM;
|
||||||
|
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(writer, false));
|
||||||
|
IndexFieldData.XFieldComparatorSource innerFieldComparator = createInnerFieldComparator("field2", sortMode);
|
||||||
|
Filter parentFilter = new TermFilter(new Term("__type", "parent"));
|
||||||
|
Filter childFilter = new NotFilter(parentFilter);
|
||||||
|
NestedFieldComparatorSource nestedComparatorSource = new NestedFieldComparatorSource(sortMode, innerFieldComparator, parentFilter, childFilter);
|
||||||
|
ToParentBlockJoinQuery query = new ToParentBlockJoinQuery(new XFilteredQuery(new MatchAllDocsQuery(), childFilter), new CachingWrapperFilter(parentFilter), ScoreMode.None);
|
||||||
|
|
||||||
|
Sort sort = new Sort(new SortField("field2", nestedComparatorSource));
|
||||||
|
TopFieldDocs topDocs = searcher.search(query, 5, sort);
|
||||||
|
assertThat(topDocs.totalHits, equalTo(7));
|
||||||
|
assertThat(topDocs.scoreDocs.length, equalTo(5));
|
||||||
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(11));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).intValue(), equalTo(7));
|
||||||
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(7));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).intValue(), equalTo(8));
|
||||||
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(3));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).intValue(), equalTo(9));
|
||||||
|
assertThat(topDocs.scoreDocs[3].doc, equalTo(15));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).intValue(), equalTo(10));
|
||||||
|
assertThat(topDocs.scoreDocs[4].doc, equalTo(19));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(11));
|
||||||
|
|
||||||
|
sort = new Sort(new SortField("field2", nestedComparatorSource, true));
|
||||||
|
topDocs = searcher.search(query, 5, sort);
|
||||||
|
assertThat(topDocs.totalHits, equalTo(7));
|
||||||
|
assertThat(topDocs.scoreDocs.length, equalTo(5));
|
||||||
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(28));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).intValue(), equalTo(13));
|
||||||
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(23));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).intValue(), equalTo(12));
|
||||||
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(19));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).intValue(), equalTo(11));
|
||||||
|
assertThat(topDocs.scoreDocs[3].doc, equalTo(15));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).intValue(), equalTo(10));
|
||||||
|
assertThat(topDocs.scoreDocs[4].doc, equalTo(3));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(9));
|
||||||
|
|
||||||
|
childFilter = new AndFilter(Arrays.asList(new NotFilter(parentFilter), new TermFilter(new Term("filter_1", "T"))));
|
||||||
|
nestedComparatorSource = new NestedFieldComparatorSource(sortMode, innerFieldComparator, parentFilter, childFilter);
|
||||||
|
query = new ToParentBlockJoinQuery(
|
||||||
|
new XFilteredQuery(new MatchAllDocsQuery(), childFilter),
|
||||||
|
new CachingWrapperFilter(parentFilter),
|
||||||
|
ScoreMode.None
|
||||||
|
);
|
||||||
|
sort = new Sort(new SortField("field2", nestedComparatorSource, true));
|
||||||
|
topDocs = searcher.search(query, 5, sort);
|
||||||
|
assertThat(topDocs.totalHits, equalTo(6));
|
||||||
|
assertThat(topDocs.scoreDocs.length, equalTo(5));
|
||||||
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(23));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).intValue(), equalTo(12));
|
||||||
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(3));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).intValue(), equalTo(9));
|
||||||
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(7));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).intValue(), equalTo(8));
|
||||||
|
assertThat(topDocs.scoreDocs[3].doc, equalTo(11));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).intValue(), equalTo(7));
|
||||||
|
assertThat(topDocs.scoreDocs[4].doc, equalTo(15));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(3));
|
||||||
|
|
||||||
|
sort = new Sort(new SortField("field2", nestedComparatorSource));
|
||||||
|
topDocs = searcher.search(query, 5, sort);
|
||||||
|
assertThat(topDocs.totalHits, equalTo(6));
|
||||||
|
assertThat(topDocs.scoreDocs.length, equalTo(5));
|
||||||
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(15));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(28));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(11));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).intValue(), equalTo(7));
|
||||||
|
assertThat(topDocs.scoreDocs[3].doc, equalTo(7));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).intValue(), equalTo(8));
|
||||||
|
assertThat(topDocs.scoreDocs[4].doc, equalTo(3));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(9));
|
||||||
|
|
||||||
|
// Moved to method, because floating point based XFieldComparatorSource have different outcome for SortMode avg,
|
||||||
|
// than integral number based implementations...
|
||||||
|
assertAvgScoreMode(parentFilter, searcher, innerFieldComparator);
|
||||||
|
searcher.getIndexReader().close();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void assertAvgScoreMode(Filter parentFilter, IndexSearcher searcher, IndexFieldData.XFieldComparatorSource innerFieldComparator) throws IOException {
|
||||||
|
SortMode sortMode = SortMode.AVG;
|
||||||
|
Filter childFilter = new NotFilter(parentFilter);
|
||||||
|
NestedFieldComparatorSource nestedComparatorSource = new NestedFieldComparatorSource(sortMode, innerFieldComparator, parentFilter, childFilter);
|
||||||
|
Query query = new ToParentBlockJoinQuery(new XFilteredQuery(new MatchAllDocsQuery(), childFilter), new CachingWrapperFilter(parentFilter), ScoreMode.None);
|
||||||
|
Sort sort = new Sort(new SortField("field2", nestedComparatorSource));
|
||||||
|
TopDocs topDocs = searcher.search(query, 5, sort);
|
||||||
|
assertThat(topDocs.totalHits, equalTo(7));
|
||||||
|
assertThat(topDocs.scoreDocs.length, equalTo(5));
|
||||||
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(7));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).intValue(), equalTo(2));
|
||||||
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(11));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).intValue(), equalTo(2));
|
||||||
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(3));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[3].doc, equalTo(15));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[4].doc, equalTo(19));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract IndexableField createField(String name, int value, Field.Store store);
|
||||||
|
|
||||||
|
protected abstract IndexFieldData.XFieldComparatorSource createInnerFieldComparator(String fieldName, SortMode sortMode);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.test.unit.index.search.nested;
|
||||||
|
|
||||||
|
import org.apache.lucene.document.Field;
|
||||||
|
import org.apache.lucene.document.IntField;
|
||||||
|
import org.apache.lucene.index.IndexableField;
|
||||||
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.ByteValuesComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
|
import org.elasticsearch.index.fielddata.plain.ByteArrayIndexFieldData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class ByteNestedSortingTests extends AbstractNumberNestedSortingTests {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FieldDataType getFieldDataType() {
|
||||||
|
return new FieldDataType("byte");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IndexFieldData.XFieldComparatorSource createInnerFieldComparator(String fieldName, SortMode sortMode) {
|
||||||
|
ByteArrayIndexFieldData fieldData = getForField(fieldName);
|
||||||
|
return new ByteValuesComparatorSource(fieldData, null, sortMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IndexableField createField(String name, int value, Field.Store store) {
|
||||||
|
return new IntField(name, value, store);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.test.unit.index.search.nested;
|
||||||
|
|
||||||
|
import org.apache.lucene.document.DoubleField;
|
||||||
|
import org.apache.lucene.document.Field;
|
||||||
|
import org.apache.lucene.index.IndexableField;
|
||||||
|
import org.apache.lucene.search.*;
|
||||||
|
import org.apache.lucene.search.join.ScoreMode;
|
||||||
|
import org.apache.lucene.search.join.ToParentBlockJoinQuery;
|
||||||
|
import org.elasticsearch.common.lucene.search.NotFilter;
|
||||||
|
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||||
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
|
import org.elasticsearch.index.fielddata.plain.DoubleArrayIndexFieldData;
|
||||||
|
import org.elasticsearch.index.search.nested.NestedFieldComparatorSource;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class DoubleNestedSortingTests extends AbstractNumberNestedSortingTests {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FieldDataType getFieldDataType() {
|
||||||
|
return new FieldDataType("double");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IndexFieldData.XFieldComparatorSource createInnerFieldComparator(String fieldName, SortMode sortMode) {
|
||||||
|
DoubleArrayIndexFieldData fieldData = getForField(fieldName);
|
||||||
|
return new DoubleValuesComparatorSource(fieldData, null, sortMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IndexableField createField(String name, int value, Field.Store store) {
|
||||||
|
return new DoubleField(name, value, store);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void assertAvgScoreMode(Filter parentFilter, IndexSearcher searcher, IndexFieldData.XFieldComparatorSource innerFieldComparator) throws IOException {
|
||||||
|
SortMode sortMode = SortMode.AVG;
|
||||||
|
Filter childFilter = new NotFilter(parentFilter);
|
||||||
|
NestedFieldComparatorSource nestedComparatorSource = new NestedFieldComparatorSource(sortMode, innerFieldComparator, parentFilter, childFilter);
|
||||||
|
Query query = new ToParentBlockJoinQuery(new XFilteredQuery(new MatchAllDocsQuery(), childFilter), new CachingWrapperFilter(parentFilter), ScoreMode.None);
|
||||||
|
Sort sort = new Sort(new SortField("field2", nestedComparatorSource));
|
||||||
|
TopDocs topDocs = searcher.search(query, 5, sort);
|
||||||
|
assertThat(topDocs.totalHits, equalTo(7));
|
||||||
|
assertThat(topDocs.scoreDocs.length, equalTo(5));
|
||||||
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(11));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).intValue(), equalTo(2));
|
||||||
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(7));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).intValue(), equalTo(2));
|
||||||
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(3));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[3].doc, equalTo(15));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[4].doc, equalTo(19));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.test.unit.index.search.nested;
|
||||||
|
|
||||||
|
import org.apache.lucene.document.Field;
|
||||||
|
import org.apache.lucene.document.FloatField;
|
||||||
|
import org.apache.lucene.index.IndexableField;
|
||||||
|
import org.apache.lucene.search.*;
|
||||||
|
import org.apache.lucene.search.join.ScoreMode;
|
||||||
|
import org.apache.lucene.search.join.ToParentBlockJoinQuery;
|
||||||
|
import org.elasticsearch.common.lucene.search.NotFilter;
|
||||||
|
import org.elasticsearch.common.lucene.search.XFilteredQuery;
|
||||||
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.FloatValuesComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
|
import org.elasticsearch.index.fielddata.plain.FloatArrayIndexFieldData;
|
||||||
|
import org.elasticsearch.index.search.nested.NestedFieldComparatorSource;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class FloatNestedSortingTests extends AbstractNumberNestedSortingTests {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FieldDataType getFieldDataType() {
|
||||||
|
return new FieldDataType("float");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IndexFieldData.XFieldComparatorSource createInnerFieldComparator(String fieldName, SortMode sortMode) {
|
||||||
|
FloatArrayIndexFieldData fieldData = getForField(fieldName);
|
||||||
|
return new FloatValuesComparatorSource(fieldData, null, sortMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IndexableField createField(String name, int value, Field.Store store) {
|
||||||
|
return new FloatField(name, value, store);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void assertAvgScoreMode(Filter parentFilter, IndexSearcher searcher, IndexFieldData.XFieldComparatorSource innerFieldComparator) throws IOException {
|
||||||
|
SortMode sortMode = SortMode.AVG;
|
||||||
|
Filter childFilter = new NotFilter(parentFilter);
|
||||||
|
NestedFieldComparatorSource nestedComparatorSource = new NestedFieldComparatorSource(sortMode, innerFieldComparator, parentFilter, childFilter);
|
||||||
|
Query query = new ToParentBlockJoinQuery(new XFilteredQuery(new MatchAllDocsQuery(), childFilter), new CachingWrapperFilter(parentFilter), ScoreMode.None);
|
||||||
|
Sort sort = new Sort(new SortField("field2", nestedComparatorSource));
|
||||||
|
TopDocs topDocs = searcher.search(query, 5, sort);
|
||||||
|
assertThat(topDocs.totalHits, equalTo(7));
|
||||||
|
assertThat(topDocs.scoreDocs.length, equalTo(5));
|
||||||
|
assertThat(topDocs.scoreDocs[0].doc, equalTo(11));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).intValue(), equalTo(2));
|
||||||
|
assertThat(topDocs.scoreDocs[1].doc, equalTo(7));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).intValue(), equalTo(2));
|
||||||
|
assertThat(topDocs.scoreDocs[2].doc, equalTo(3));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[3].doc, equalTo(15));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).intValue(), equalTo(3));
|
||||||
|
assertThat(topDocs.scoreDocs[4].doc, equalTo(19));
|
||||||
|
assertThat(((Number) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).intValue(), equalTo(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.test.unit.index.search.nested;
|
||||||
|
|
||||||
|
import org.apache.lucene.document.Field;
|
||||||
|
import org.apache.lucene.document.IntField;
|
||||||
|
import org.apache.lucene.index.IndexableField;
|
||||||
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.IntValuesComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
|
import org.elasticsearch.index.fielddata.plain.IntArrayIndexFieldData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class IntegerNestedSortingTests extends AbstractNumberNestedSortingTests {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FieldDataType getFieldDataType() {
|
||||||
|
return new FieldDataType("int");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IndexFieldData.XFieldComparatorSource createInnerFieldComparator(String fieldName, SortMode sortMode) {
|
||||||
|
IntArrayIndexFieldData fieldData = getForField(fieldName);
|
||||||
|
return new IntValuesComparatorSource(fieldData, null, sortMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IndexableField createField(String name, int value, Field.Store store) {
|
||||||
|
return new IntField(name, value, store);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.test.unit.index.search.nested;
|
||||||
|
|
||||||
|
import org.apache.lucene.document.Field;
|
||||||
|
import org.apache.lucene.document.LongField;
|
||||||
|
import org.apache.lucene.index.IndexableField;
|
||||||
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
|
import org.elasticsearch.index.fielddata.plain.LongArrayIndexFieldData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class LongNestedSortingTests extends AbstractNumberNestedSortingTests {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FieldDataType getFieldDataType() {
|
||||||
|
return new FieldDataType("long");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IndexFieldData.XFieldComparatorSource createInnerFieldComparator(String fieldName, SortMode sortMode) {
|
||||||
|
LongArrayIndexFieldData fieldData = getForField(fieldName);
|
||||||
|
return new LongValuesComparatorSource(fieldData, null, sortMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IndexableField createField(String name, int value, Field.Store store) {
|
||||||
|
return new LongField(name, value, store);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,3 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.elasticsearch.test.unit.index.search.nested;
|
package org.elasticsearch.test.unit.index.search.nested;
|
||||||
|
|
||||||
import org.apache.lucene.document.Document;
|
import org.apache.lucene.document.Document;
|
||||||
@ -31,7 +51,7 @@ import static org.hamcrest.Matchers.equalTo;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class NestedFieldComparatorTests extends AbstractFieldDataTests {
|
public class NestedSortingTests extends AbstractFieldDataTests {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FieldDataType getFieldDataType() {
|
protected FieldDataType getFieldDataType() {
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to ElasticSearch and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. ElasticSearch 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.test.unit.index.search.nested;
|
||||||
|
|
||||||
|
import org.apache.lucene.document.Field;
|
||||||
|
import org.apache.lucene.document.IntField;
|
||||||
|
import org.apache.lucene.index.IndexableField;
|
||||||
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.ShortValuesComparatorSource;
|
||||||
|
import org.elasticsearch.index.fielddata.fieldcomparator.SortMode;
|
||||||
|
import org.elasticsearch.index.fielddata.plain.ShortArrayIndexFieldData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public class ShortNestedSortingTests extends AbstractNumberNestedSortingTests {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FieldDataType getFieldDataType() {
|
||||||
|
return new FieldDataType("short");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IndexFieldData.XFieldComparatorSource createInnerFieldComparator(String fieldName, SortMode sortMode) {
|
||||||
|
ShortArrayIndexFieldData fieldData = getForField(fieldName);
|
||||||
|
return new ShortValuesComparatorSource(fieldData, null, sortMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IndexableField createField(String name, int value, Field.Store store) {
|
||||||
|
return new IntField(name, value, store);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user