use of com.xiaomi.linden.thrift.common.LindenResult in project linden by XiaoMi.
the class CoreLindenCluster method coreSearch.
public LindenResult coreSearch(final LindenSearchRequest request) throws IOException {
List<Future<BoxedUnit>> futures = new ArrayList<>();
List<String> hosts = new ArrayList<>();
final List<LindenResult> resultList = new ArrayList<>();
if (request.isSetRouteParam() && request.getRouteParam().isSetShardParams()) {
for (final ShardRouteParam routeParam : request.getRouteParam().getShardParams()) {
ShardClient client = clients.get(routeParam.getShardId());
if (client != null && client.isAvailable()) {
LindenSearchRequest subRequest = request;
if (routeParam.isSetEarlyParam()) {
subRequest = new LindenSearchRequest(request);
subRequest.setEarlyParam(routeParam.getEarlyParam());
}
final Map.Entry<String, Future<LindenResult>> hostFuturePair = client.search(subRequest);
hosts.add(hostFuturePair.getKey());
futures.add(hostFuturePair.getValue().transformedBy(new FutureTransformer<LindenResult, BoxedUnit>() {
@Override
public BoxedUnit map(LindenResult lindenResult) {
synchronized (resultList) {
resultList.add(lindenResult);
if (!lindenResult.isSuccess()) {
LOGGER.error("Shard [{}] host [{}] failed to get search result : {}", routeParam.getShardId(), hostFuturePair.getKey(), lindenResult.getError());
}
}
return BoxedUnit.UNIT;
}
@Override
public BoxedUnit handle(Throwable t) {
LOGGER.error("Shard [{}] host [{}] failed to get search result : {}", routeParam.getShardId(), hostFuturePair.getKey(), Throwables.getStackTraceAsString(t));
return BoxedUnit.UNIT;
}
}));
} else {
LOGGER.warn("Route to Shard [{}] failed.", routeParam.getShardId());
}
}
} else {
LindenSearchRequest subRequest = request;
for (final Map.Entry<Integer, ShardClient> entry : clients.entrySet()) {
if (entry.getValue().isAvailable()) {
final Map.Entry<String, Future<LindenResult>> hostFuturePair = entry.getValue().search(subRequest);
hosts.add(hostFuturePair.getKey());
futures.add(hostFuturePair.getValue().transformedBy(new FutureTransformer<LindenResult, BoxedUnit>() {
@Override
public BoxedUnit map(LindenResult lindenResult) {
synchronized (resultList) {
resultList.add(lindenResult);
if (!lindenResult.isSuccess()) {
LOGGER.error("Shard [{}] host [{}] failed to get search result : {}", entry.getKey(), hostFuturePair.getKey(), lindenResult.getError());
}
return BoxedUnit.UNIT;
}
}
@Override
public BoxedUnit handle(Throwable t) {
LOGGER.error("Shard [{}] host [{}] failed to get search result : {}", entry.getKey(), hostFuturePair.getKey(), Throwables.getStackTraceAsString(t));
return BoxedUnit.UNIT;
}
}));
}
}
}
Future<List<BoxedUnit>> collected = Future.collect(futures);
try {
if (clusterFutureAwaitTimeout == 0) {
Await.result(collected);
} else {
Await.result(collected, Duration.apply(clusterFutureAwaitTimeout, TimeUnit.MILLISECONDS));
}
} catch (Exception e) {
LOGGER.error("Failed to get all results, exception: {}", Throwables.getStackTraceAsString(e));
LOGGER.error(getHostFutureInfo(hosts, futures));
if (resultList.size() == 0) {
return new LindenResult().setSuccess(false).setError("Failed to get any shard result, " + Throwables.getStackTraceAsString(e));
}
}
return ResultMerger.merge(request, resultList);
}
use of com.xiaomi.linden.thrift.common.LindenResult in project linden by XiaoMi.
the class ResultMerger method merge.
public static LindenResult merge(final LindenSearchRequest lindenRequest, final List<LindenResult> resultList) {
if (resultList == null || resultList.isEmpty()) {
return EMPTY_RESULT;
}
Iterator<LindenResult> iterator = resultList.iterator();
int failureCount = 0;
LindenResult failedResult = null;
while (iterator.hasNext()) {
LindenResult result = iterator.next();
if (!result.isSuccess()) {
failureCount++;
failedResult = result;
iterator.remove();
}
}
if (resultList.isEmpty()) {
if (failureCount == 1) {
LOGGER.error("The shard failed for search request {}", lindenRequest.toString());
return failedResult;
}
LOGGER.error("All shards failed for search request {}", lindenRequest.toString());
return ALL_SHARDS_FAILED_RESULT;
}
LindenResult mergedResult;
if (lindenRequest.isSetGroupParam()) {
// merge results for grouping search
mergedResult = mergeGroupSearch(lindenRequest, resultList);
} else {
// merge results for normal searching
mergedResult = new LindenResult().setTotalHits(0).setQueryInfo(resultList.get(0).queryInfo);
List<List<LindenHit>> hits = new ArrayList<>();
for (LindenResult result : resultList) {
mergedResult.totalHits += result.getTotalHits();
hits.add(result.getHits());
}
// merge LindenHit
List<LindenSortField> sortFields = lindenRequest.isSetSort() ? lindenRequest.getSort().getFields() : null;
Iterable<LindenHit> mergedHits = Iterables.mergeSorted(hits, new LindenHitCmp(sortFields));
List<LindenHit> topNHits = Lists.newArrayList(mergedHits);
if (lindenRequest.getOffset() <= topNHits.size()) {
List<LindenHit> subHits = topNHits.subList(lindenRequest.getOffset(), Math.min(lindenRequest.getOffset() + lindenRequest.getLength(), topNHits.size()));
mergedResult.setHits(subHits);
} else {
mergedResult.setHits(new ArrayList<LindenHit>());
}
}
// Merge facet result
if (lindenRequest.isSetFacet()) {
mergeFacet(lindenRequest, resultList, mergedResult);
}
if (failureCount > 0) {
mergedResult.setError(failureCount + " shards failed.");
}
return mergedResult;
}
use of com.xiaomi.linden.thrift.common.LindenResult in project linden by XiaoMi.
the class TestHadoopIndexingInOneBox method searchTest.
@Test
public void searchTest() throws Exception {
System.out.println("Start basicTest");
LindenSearchRequest request = new LindenSearchRequest();
LindenResult result = lindenCore.search(request);
Assert.assertEquals(15000, result.getTotalHits());
request = bqlCompiler.compile("select * from linden where color='green'").getSearchRequest();
result = lindenCore.search(request);
Assert.assertEquals(1084, result.getTotalHits());
request = bqlCompiler.compile("select * from linden where price=7000").getSearchRequest();
result = lindenCore.search(request);
Assert.assertEquals(148, result.getTotalHits());
request = bqlCompiler.compile("select * from linden by query is \"contents:(compact AND green)\"").getSearchRequest();
result = lindenCore.search(request);
Assert.assertEquals(589, result.getTotalHits());
Assert.assertEquals(1.0581597089767456, result.getHits().get(0).getScore(), 1e-16);
request = bqlCompiler.compile("select * from linden browse by color(3), makemodel drill sideways makemodel('european/audi') source").getSearchRequest();
result = lindenCore.search(request);
Assert.assertEquals(2, result.getFacetResults().size());
Assert.assertEquals(403, result.getFacetResults().get(0).getValue());
Assert.assertEquals(8, result.getFacetResults().get(0).getChildCount());
Assert.assertEquals("black", result.getFacetResults().get(0).getLabelValues().get(0).getLabel());
Assert.assertEquals(131, result.getFacetResults().get(0).getLabelValues().get(0).getValue());
Assert.assertEquals(15000, result.getFacetResults().get(1).getValue());
Assert.assertEquals(3, result.getFacetResults().get(1).getChildCount());
Assert.assertEquals("asian", result.getFacetResults().get(1).getLabelValues().get(0).getLabel());
Assert.assertEquals(5470, result.getFacetResults().get(1).getLabelValues().get(0).getValue());
lindenCore.close();
}
use of com.xiaomi.linden.thrift.common.LindenResult in project linden by XiaoMi.
the class LindenResultParser method parse.
public LindenResult parse(TopDocs topDocs, TopGroups<TopDocs> topGroupedDocs, Facets facets, FacetsCollector facetsCollector) throws IOException {
LindenResult result = new LindenResult();
List<LindenHit> lindenHits;
int totalHits = 0;
if (topDocs != null) {
totalHits = topDocs.totalHits;
lindenHits = parseLindenHits(topDocs.scoreDocs);
} else if (topGroupedDocs != null) {
lindenHits = new ArrayList<>();
totalHits = topGroupedDocs.totalHitCount;
for (GroupDocs<TopDocs> group : topGroupedDocs.groups) {
List<LindenHit> groupHits = parseLindenHits(group.scoreDocs);
LindenHit hitGroup = new LindenHit(groupHits.get(0)).setGroupHits(groupHits);
String groupField = request.getGroupParam().getGroupField();
String groupValue = LindenUtil.getFieldStringValue(leaves, group.scoreDocs[0].doc, groupField);
if (!hitGroup.isSetFields()) {
hitGroup.setFields(new HashMap<String, String>());
}
hitGroup.getFields().put(groupField, groupValue);
lindenHits.add(hitGroup);
}
int groupTotal = topGroupedDocs.totalGroupCount == null ? 0 : topGroupedDocs.totalGroupCount;
result.setTotalGroups(groupTotal);
result.setTotalGroupHits(topGroupedDocs.totalGroupedHitCount);
} else {
lindenHits = new ArrayList<>();
}
result.setTotalHits(totalHits);
result.setHits(lindenHits);
parseFacets(result, facets, facetsCollector);
result.setQueryInfo(new QueryInfo().setQuery(query.toString()));
if (filter != null) {
result.getQueryInfo().setFilter(filter.toString());
}
if (sort != null) {
result.getQueryInfo().setSort(sort.toString());
}
return result;
}
use of com.xiaomi.linden.thrift.common.LindenResult in project linden by XiaoMi.
the class TestLindenCore method flexibleQueryTest.
@Test
public void flexibleQueryTest() throws IOException {
String function = " float sum = 0;\n" + " for (int i = 0; i < getFieldLength(); ++i) {\n" + " for (int j = 0; j < getTermLength(); ++j) {\n" + " sum += 100 * getScore(i, j) * rank();\n" + " }\n" + " }\n" + " return sum;";
LindenQuery flexQuery = new LindenFlexibleQueryBuilder().setQuery("lucene").addField("title").addModel("test", function).build();
LindenResult result = lindenCore.search(new LindenSearchRequest().setQuery(flexQuery));
Assert.assertEquals(4, result.getTotalHits());
flexQuery = new LindenFlexibleQueryBuilder().setQuery("lucene 1").addField("title").addModel("test", function).setFullMatch(true).build();
result = lindenCore.search(new LindenSearchRequest().setQuery(flexQuery));
Assert.assertEquals(1, result.getTotalHits());
}
Aggregations