package org.apache.solr.handler.component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.solr.BaseDistributedSearchTestCase;
import org.apache.solr.client.solrj.response.PivotField;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.params.FacetParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.NamedList;
public class DistributedFacetPivotTest extends BaseDistributedSearchTestCase {
@Override
public void doTest() throws Exception {
del("*:*");
index(id, 19, "place_t", "cardiff dublin", "company_t", "microsoft polecat");
index(id, 20, "place_t", "dublin", "company_t", "polecat microsoft honda");
index(id, 21, "place_t", "london la dublin", "company_t",
"microsoft fujitsu honda polecat");
index(id, 22, "place_t", "krakow london cardiff", "company_t",
"polecat honda bbc");
index(id, 23, "place_t", "london", "company_t", "");
index(id, 24, "place_t", "la", "company_t", "");
index(id, 25, "place_t", "", "company_t",
"microsoft polecat honda fujitsu honda bbc");
index(id, 26, "place_t", "krakow", "company_t", "honda");
index(id, 27, "place_t", "krakow cardiff dublin london la", "company_t",
"honda microsoft polecat bbc fujitsu");
index(id, 28, "place_t", "cork", "company_t",
"fujitsu rte");
commit();
handle.clear();
handle.put("QTime", SKIPVAL);
final ModifiableSolrParams params = new ModifiableSolrParams();
setDistributedParams(params);
params.add("q", "*:*");
params.add("facet", "true");
params.add("facet.pivot", "place_t,company_t");
params.set(FacetParams.FACET_SORT, FacetParams.FACET_SORT_INDEX);
QueryResponse rsp = queryServer(params);
List<PivotField> expectedPlacePivots = new UnorderedEqualityArrayList<PivotField>();
List<PivotField> expectedCardiffPivots = new UnorderedEqualityArrayList<PivotField>();
expectedCardiffPivots.add(new ComparablePivotField("company_t",
"microsoft", 2, null, null));
expectedCardiffPivots.add(new ComparablePivotField("company_t", "honda", 2,
null, null));
expectedCardiffPivots.add(new ComparablePivotField("company_t", "bbc", 2,
null, null));
expectedCardiffPivots.add(new ComparablePivotField("company_t", "polecat",
3, null, null));
expectedCardiffPivots.add(new ComparablePivotField("company_t", "fujitsu",
1, null, null));
List<PivotField> expectedDublinPivots = new UnorderedEqualityArrayList<PivotField>();
expectedDublinPivots.add(new ComparablePivotField("company_t", "polecat",
4, null, null));
expectedDublinPivots.add(new ComparablePivotField("company_t", "microsoft",
4, null, null));
expectedDublinPivots.add(new ComparablePivotField("company_t", "honda", 3,
null, null));
expectedDublinPivots.add(new ComparablePivotField("company_t", "fujitsu",
2, null, null));
expectedDublinPivots.add(new ComparablePivotField("company_t", "bbc", 1,
null, null));
List<PivotField> expectedLondonPivots = new UnorderedEqualityArrayList<PivotField>();
expectedLondonPivots.add(new ComparablePivotField("company_t", "polecat",
3, null, null));
expectedLondonPivots.add(new ComparablePivotField("company_t", "microsoft",
2, null, null));
expectedLondonPivots.add(new ComparablePivotField("company_t", "fujitsu",
2, null, null));
expectedLondonPivots.add(new ComparablePivotField("company_t", "honda", 3,
null, null));
expectedLondonPivots.add(new ComparablePivotField("company_t", "bbc", 2,
null, null));
List<PivotField> expectedLAPivots = new UnorderedEqualityArrayList<PivotField>();
expectedLAPivots.add(new ComparablePivotField("company_t", "microsoft", 2,
null, null));
expectedLAPivots.add(new ComparablePivotField("company_t", "fujitsu", 2,
null, null));
expectedLAPivots
.add(new ComparablePivotField("company_t", "honda", 2, null, null));
expectedLAPivots.add(new ComparablePivotField("company_t", "bbc", 1, null, null));
expectedLAPivots.add(new ComparablePivotField("company_t", "polecat", 2,
null, null));
List<PivotField> expectedKrakowPivots = new UnorderedEqualityArrayList<PivotField>();
expectedKrakowPivots.add(new ComparablePivotField("company_t", "polecat",
2, null));
expectedKrakowPivots.add(new ComparablePivotField("company_t", "bbc", 2,
null));
expectedKrakowPivots.add(new ComparablePivotField("company_t", "honda", 3,
null));
expectedKrakowPivots.add(new ComparablePivotField("company_t", "fujitsu",
1, null));
expectedKrakowPivots.add(new ComparablePivotField("company_t", "microsoft",
1, null));
List<PivotField> expectedCorkPivots = new UnorderedEqualityArrayList<PivotField>();
expectedCorkPivots.add(new ComparablePivotField("company_t", "fujitsu",
1, null));
expectedCorkPivots.add(new ComparablePivotField("company_t", "rte",
1, null));
expectedPlacePivots.add(new ComparablePivotField("place_t", "dublin", 4,
expectedDublinPivots));
expectedPlacePivots.add(new ComparablePivotField("place_t", "cardiff", 3,
expectedCardiffPivots));
expectedPlacePivots.add(new ComparablePivotField("place_t", "london", 4,
expectedLondonPivots));
expectedPlacePivots.add(new ComparablePivotField("place_t", "la", 3,
expectedLAPivots));
expectedPlacePivots.add(new ComparablePivotField("place_t", "krakow", 3,
expectedKrakowPivots));
expectedPlacePivots.add(new ComparablePivotField("place_t", "cork", 1,
expectedCorkPivots));
List<PivotField> placePivots = rsp.getFacetPivot().get("place_t,company_t");
// Useful to check for errors, orders lists and does toString() equality
// check
// testOrderedPivotsStringEquality(expectedPlacePivots, placePivots);
assertEquals(expectedPlacePivots, placePivots);
// Test sorting by count
params.remove(FacetParams.FACET_SORT);
rsp = queryServer(params);
placePivots = rsp.getFacetPivot().get("place_t,company_t");
testCountSorting(placePivots);
// Test limit
params.set(FacetParams.FACET_LIMIT, 2);
rsp = queryServer(params);
expectedPlacePivots = new UnorderedEqualityArrayList<PivotField>();
expectedDublinPivots = new UnorderedEqualityArrayList<PivotField>();
expectedDublinPivots.add(new ComparablePivotField("company_t", "polecat",
4, null));
expectedDublinPivots.add(new ComparablePivotField("company_t", "microsoft",
4, null));
expectedLondonPivots = new UnorderedEqualityArrayList<PivotField>();
expectedLondonPivots.add(new ComparablePivotField("company_t", "honda", 3,
null));
expectedLondonPivots.add(new ComparablePivotField("company_t", "polecat", 3,
null));
expectedPlacePivots.add(new ComparablePivotField("place_t", "dublin", 4,
expectedDublinPivots));
expectedPlacePivots.add(new ComparablePivotField("place_t", "london", 4,
expectedLondonPivots));
placePivots = rsp.getFacetPivot().get("place_t,company_t");
assertEquals(expectedPlacePivots, placePivots);
// Test combined limiting method
params.set(FacetParams.FACET_PIVOT_LIMIT_METHOD, FacetParams.COMBINED_PIVOT_FACET_LIMIT);
rsp = queryServer(params);
expectedPlacePivots = new UnorderedEqualityArrayList<PivotField>();
expectedDublinPivots = new UnorderedEqualityArrayList<PivotField>();
expectedDublinPivots.add(new ComparablePivotField("company_t", "polecat",
4, null));
expectedDublinPivots.add(new ComparablePivotField("company_t", "honda",
3, null));
expectedLondonPivots = new UnorderedEqualityArrayList<PivotField>();
expectedLondonPivots.add(new ComparablePivotField("company_t", "honda", 3,
null));
expectedLondonPivots.add(new ComparablePivotField("company_t", "polecat", 3,
null));
expectedPlacePivots.add(new ComparablePivotField("place_t", "dublin", 4,
expectedDublinPivots));
expectedPlacePivots.add(new ComparablePivotField("place_t", "london", 4,
expectedLondonPivots));
placePivots = rsp.getFacetPivot().get("place_t,company_t");
assertEquals(expectedPlacePivots, placePivots);
// Test pivot limit field ignore
params.set(FacetParams.FACET_PIVOT_LIMIT_IGNORE, "place_t");
rsp = queryServer(params);
expectedPlacePivots = new UnorderedEqualityArrayList<PivotField>();
expectedCardiffPivots = new UnorderedEqualityArrayList<PivotField>();
expectedCardiffPivots.add(new ComparablePivotField("company_t", "honda", 2,
null));
expectedCardiffPivots.add(new ComparablePivotField("company_t", "polecat",
3, null));
expectedDublinPivots = new UnorderedEqualityArrayList<PivotField>();
expectedDublinPivots.add(new ComparablePivotField("company_t", "polecat",
4, null));
expectedDublinPivots.add(new ComparablePivotField("company_t", "honda", 3,
null));
expectedLondonPivots = new UnorderedEqualityArrayList<PivotField>();
expectedLondonPivots.add(new ComparablePivotField("company_t", "polecat",
3, null));
expectedLondonPivots.add(new ComparablePivotField("company_t", "honda", 3,
null));
expectedLAPivots = new UnorderedEqualityArrayList<PivotField>();
expectedLAPivots
.add(new ComparablePivotField("company_t", "honda", 2, null));
expectedLAPivots.add(new ComparablePivotField("company_t", "polecat", 2,
null));
expectedKrakowPivots = new UnorderedEqualityArrayList<PivotField>();
expectedKrakowPivots.add(new ComparablePivotField("company_t", "polecat",
2, null));
expectedKrakowPivots.add(new ComparablePivotField("company_t", "honda", 3,
null));
expectedCorkPivots = new UnorderedEqualityArrayList<PivotField>();
expectedPlacePivots.add(new ComparablePivotField("place_t", "dublin", 4,
expectedDublinPivots));
expectedPlacePivots.add(new ComparablePivotField("place_t", "cardiff", 3,
expectedCardiffPivots));
expectedPlacePivots.add(new ComparablePivotField("place_t", "london", 4,
expectedLondonPivots));
expectedPlacePivots.add(new ComparablePivotField("place_t", "la", 3,
expectedLAPivots));
expectedPlacePivots.add(new ComparablePivotField("place_t", "krakow", 3,
expectedKrakowPivots));
expectedPlacePivots.add(new ComparablePivotField("place_t", "cork", 1,
expectedCorkPivots));
placePivots = rsp.getFacetPivot().get("place_t,company_t");
assertEquals(expectedPlacePivots, placePivots);
}
// Useful to check for errors, orders lists and does toString() equality check
private void testOrderedPivotsStringEquality(
List<PivotField> expectedPlacePivots, List<PivotField> placePivots) {
Collections.sort(expectedPlacePivots, new PivotFieldComparator());
for (PivotField expectedPivot : expectedPlacePivots) {
if (expectedPivot.getPivot() != null) {
Collections.sort(expectedPivot.getPivot(), new PivotFieldComparator());
}
}
Collections.sort(placePivots, new PivotFieldComparator());
for (PivotField pivot : placePivots) {
if (pivot.getPivot() != null) {
Collections.sort(pivot.getPivot(), new PivotFieldComparator());
}
}
assertEquals(expectedPlacePivots.toString(), placePivots.toString());
}
private void testCountSorting(List<PivotField> pivots) {
Integer lastCount = null;
for (PivotField pivot : pivots) {
if (lastCount != null) {
assertTrue(pivot.getCount() <= lastCount);
}
lastCount = pivot.getCount();
if (pivot.getPivot() != null) {
testCountSorting(pivot.getPivot());
}
}
}
public static class ComparablePivotField extends PivotField {
public ComparablePivotField(String f, Object v, int count,
List<PivotField> pivot, NamedList<Object> stats) {
super(f, v, count, pivot, stats,null);
}
public ComparablePivotField(String f, Object v, int count,
List<PivotField> pivot) {
this(f, v, count, pivot, null);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (!obj.getClass().isAssignableFrom(PivotField.class)) return false;
PivotField other = (PivotField) obj;
if (getCount() != other.getCount()) return false;
if (getField() == null) {
if (other.getField() != null) return false;
} else if (!getField().equals(other.getField())) return false;
if (getPivot() == null) {
if (other.getPivot() != null) return false;
} else if (!getPivot().equals(other.getPivot())) return false;
if (getValue() == null) {
if (other.getValue() != null) return false;
} else if (!getValue().equals(other.getValue())) return false;
if (getStatistics() == null) {
if(other.getStatistics() != null) return false;
} else if (!getStatistics().equals(other.getStatistics())) return false;
return true;
}
}
public static class UnorderedEqualityArrayList<T> extends ArrayList<T> {
@Override
public boolean equals(Object o) {
boolean equal = false;
if (o instanceof ArrayList) {
List<?> otherList = (List<?>) o;
if (size() == otherList.size()) {
equal = true;
for (Object objectInOtherList : otherList) {
if (!contains(objectInOtherList)) {
equal = false;
}
}
}
}
return equal;
}
public int indexOf(Object o) {
for (int i = 0; i < size(); i++) {
if (get(i).equals(o)) {
return i;
}
}
return -1;
}
}
public class PivotFieldComparator implements Comparator<PivotField> {
@Override
public int compare(PivotField o1, PivotField o2) {
Integer compare = (Integer.valueOf(o2.getCount())).compareTo(Integer
.valueOf(o1.getCount()));
if (compare == 0) {
compare = ((String) o2.getValue()).compareTo((String) o1.getValue());
}
return compare;
}
}
}