Search in sources :

Example 41 with LindenResult

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);
}
Also used : FutureTransformer(com.twitter.util.FutureTransformer) ArrayList(java.util.ArrayList) LindenSearchRequest(com.xiaomi.linden.thrift.common.LindenSearchRequest) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) LindenResult(com.xiaomi.linden.thrift.common.LindenResult) ShardRouteParam(com.xiaomi.linden.thrift.common.ShardRouteParam) Future(com.twitter.util.Future) ArrayList(java.util.ArrayList) List(java.util.List) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 42 with LindenResult

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;
}
Also used : ArrayList(java.util.ArrayList) LindenSortField(com.xiaomi.linden.thrift.common.LindenSortField) LindenResult(com.xiaomi.linden.thrift.common.LindenResult) LindenHit(com.xiaomi.linden.thrift.common.LindenHit) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList)

Example 43 with LindenResult

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();
}
Also used : LindenResult(com.xiaomi.linden.thrift.common.LindenResult) LindenSearchRequest(com.xiaomi.linden.thrift.common.LindenSearchRequest) Test(org.junit.Test)

Example 44 with LindenResult

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;
}
Also used : LindenResult(com.xiaomi.linden.thrift.common.LindenResult) HashMap(java.util.HashMap) LindenHit(com.xiaomi.linden.thrift.common.LindenHit) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) GroupDocs(org.apache.lucene.search.grouping.GroupDocs) QueryInfo(com.xiaomi.linden.thrift.common.QueryInfo)

Example 45 with LindenResult

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());
}
Also used : LindenResult(com.xiaomi.linden.thrift.common.LindenResult) LindenFlexibleQueryBuilder(com.xiaomi.linden.thrift.builder.query.LindenFlexibleQueryBuilder) LindenQuery(com.xiaomi.linden.thrift.common.LindenQuery) LindenSearchRequest(com.xiaomi.linden.thrift.common.LindenSearchRequest) Test(org.junit.Test)

Aggregations

LindenResult (com.xiaomi.linden.thrift.common.LindenResult)79 LindenSearchRequest (com.xiaomi.linden.thrift.common.LindenSearchRequest)69 Test (org.junit.Test)69 IOException (java.io.IOException)7 LindenQuery (com.xiaomi.linden.thrift.common.LindenQuery)5 JSONObject (com.alibaba.fastjson.JSONObject)4 Stopwatch (com.google.common.base.Stopwatch)4 MultiLindenCoreImpl (com.xiaomi.linden.core.search.MultiLindenCoreImpl)3 LindenFlexibleQueryBuilder (com.xiaomi.linden.thrift.builder.query.LindenFlexibleQueryBuilder)3 LindenDeleteRequest (com.xiaomi.linden.thrift.common.LindenDeleteRequest)3 LindenHit (com.xiaomi.linden.thrift.common.LindenHit)3 LindenRequest (com.xiaomi.linden.thrift.common.LindenRequest)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 FlexibleQuery (com.xiaomi.linden.lucene.query.flexiblequery.FlexibleQuery)2 Response (com.xiaomi.linden.thrift.common.Response)2 BooleanQuery (org.apache.lucene.search.BooleanQuery)2 DisjunctionMaxQuery (org.apache.lucene.search.DisjunctionMaxQuery)2 FilteredQuery (org.apache.lucene.search.FilteredQuery)2 Query (org.apache.lucene.search.Query)2