Example usage for org.apache.lucene.search.grouping SearchGroup SearchGroup

List of usage examples for org.apache.lucene.search.grouping SearchGroup SearchGroup

Introduction

In this page you can find the example usage for org.apache.lucene.search.grouping SearchGroup SearchGroup.

Prototype

SearchGroup

Source Link

Usage

From source file:org.apache.solr.handler.component.HelloHandlerComponent.java

License:Apache License

/**
 * Actually run the query/*from   w ww.  j a va  2  s  .c  om*/
 */
@Override
public void process(ResponseBuilder rb) throws IOException {
    SolrQueryRequest req = rb.req;
    SolrQueryResponse rsp = rb.rsp;
    SolrParams params = req.getParams();
    if (!params.getBool(COMPONENT_NAME, true)) {
        return;
    }
    SolrIndexSearcher searcher = req.getSearcher();

    if (rb.getQueryCommand().getOffset() < 0) {
        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "'start' parameter cannot be negative");
    }

    // -1 as flag if not set.
    long timeAllowed = (long) params.getInt(CommonParams.TIME_ALLOWED, -1);

    // Optional: This could also be implemented by the top-level searcher sending
    // a filter that lists the ids... that would be transparent to
    // the request handler, but would be more expensive (and would preserve score
    // too if desired).
    String ids = params.get(ShardParams.IDS);
    if (ids != null) {
        SchemaField idField = req.getSchema().getUniqueKeyField();
        List<String> idArr = StrUtils.splitSmart(ids, ",", true);
        int[] luceneIds = new int[idArr.size()];
        int docs = 0;
        for (int i = 0; i < idArr.size(); i++) {
            int id = req.getSearcher()
                    .getFirstMatch(new Term(idField.getName(), idField.getType().toInternal(idArr.get(i))));
            if (id >= 0)
                luceneIds[docs++] = id;
        }

        DocListAndSet res = new DocListAndSet();
        res.docList = new DocSlice(0, docs, luceneIds, null, docs, 0);
        if (rb.isNeedDocSet()) {
            // TODO: create a cache for this!
            List<Query> queries = new ArrayList<Query>();
            queries.add(rb.getQuery());
            List<Query> filters = rb.getFilters();
            if (filters != null)
                queries.addAll(filters);
            res.docSet = searcher.getDocSet(queries);
        }
        rb.setResults(res);

        ResultContext ctx = new ResultContext();
        ctx.docs = rb.getResults().docList;
        ctx.query = null; // anything?

        rsp.add("response", ctx);
        return;
    }

    SolrIndexSearcher.QueryCommand cmd = rb.getQueryCommand();
    cmd.setTimeAllowed(timeAllowed);
    SolrIndexSearcher.QueryResult result = new SolrIndexSearcher.QueryResult();

    //
    // grouping / field collapsing
    //
    GroupingSpecification groupingSpec = rb.getGroupingSpec();
    if (groupingSpec != null) {
        try {
            boolean needScores = (cmd.getFlags() & SolrIndexSearcher.GET_SCORES) != 0;
            if (params.getBool(GroupParams.GROUP_DISTRIBUTED_FIRST, false)) {
                CommandHandler.Builder topsGroupsActionBuilder = new CommandHandler.Builder()
                        .setQueryCommand(cmd).setNeedDocSet(false) // Order matters here
                        .setIncludeHitCount(true).setSearcher(searcher);

                for (String field : groupingSpec.getFields()) {
                    topsGroupsActionBuilder.addCommandField(new SearchGroupsFieldCommand.Builder()
                            .setField(searcher.getSchema().getField(field))
                            .setGroupSort(groupingSpec.getGroupSort())
                            .setTopNGroups(cmd.getOffset() + cmd.getLen())
                            .setIncludeGroupCount(groupingSpec.isIncludeGroupCount()).build());
                }

                CommandHandler commandHandler = topsGroupsActionBuilder.build();
                commandHandler.execute();
                SearchGroupsResultTransformer serializer = new SearchGroupsResultTransformer(searcher);
                rsp.add("firstPhase", commandHandler.processResult(result, serializer));
                rsp.add("totalHitCount", commandHandler.getTotalHitCount());
                rb.setResult(result);
                return;
            } else if (params.getBool(GroupParams.GROUP_DISTRIBUTED_SECOND, false)) {
                CommandHandler.Builder secondPhaseBuilder = new CommandHandler.Builder().setQueryCommand(cmd)
                        .setTruncateGroups(
                                groupingSpec.isTruncateGroups() && groupingSpec.getFields().length > 0)
                        .setSearcher(searcher);

                for (String field : groupingSpec.getFields()) {
                    String[] topGroupsParam = params
                            .getParams(GroupParams.GROUP_DISTRIBUTED_TOPGROUPS_PREFIX + field);
                    if (topGroupsParam == null) {
                        topGroupsParam = new String[0];
                    }

                    List<SearchGroup<BytesRef>> topGroups = new ArrayList<SearchGroup<BytesRef>>(
                            topGroupsParam.length);
                    for (String topGroup : topGroupsParam) {
                        SearchGroup<BytesRef> searchGroup = new SearchGroup<BytesRef>();
                        if (!topGroup.equals(TopGroupsShardRequestFactory.GROUP_NULL_VALUE)) {
                            searchGroup.groupValue = new BytesRef(
                                    searcher.getSchema().getField(field).getType().readableToIndexed(topGroup));
                        }
                        topGroups.add(searchGroup);
                    }

                    secondPhaseBuilder.addCommandField(new TopGroupsFieldCommand.Builder()
                            .setField(searcher.getSchema().getField(field))
                            .setGroupSort(groupingSpec.getGroupSort())
                            .setSortWithinGroup(groupingSpec.getSortWithinGroup())
                            .setFirstPhaseGroups(topGroups)
                            .setMaxDocPerGroup(groupingSpec.getGroupOffset() + groupingSpec.getGroupLimit())
                            .setNeedScores(needScores).setNeedMaxScore(needScores).build());
                }

                for (String query : groupingSpec.getQueries()) {
                    secondPhaseBuilder.addCommandField(new QueryCommand.Builder()
                            .setDocsToCollect(groupingSpec.getOffset() + groupingSpec.getLimit())
                            .setSort(groupingSpec.getGroupSort()).setQuery(query, rb.req).setDocSet(searcher)
                            .build());
                }

                CommandHandler commandHandler = secondPhaseBuilder.build();
                commandHandler.execute();
                TopGroupsResultTransformer serializer = new TopGroupsResultTransformer(rb);
                rsp.add("secondPhase", commandHandler.processResult(result, serializer));
                rb.setResult(result);
                return;
            }

            int maxDocsPercentageToCache = params.getInt(GroupParams.GROUP_CACHE_PERCENTAGE, 0);
            boolean cacheSecondPassSearch = maxDocsPercentageToCache >= 1 && maxDocsPercentageToCache <= 100;
            Grouping.TotalCount defaultTotalCount = groupingSpec.isIncludeGroupCount()
                    ? Grouping.TotalCount.grouped
                    : Grouping.TotalCount.ungrouped;
            int limitDefault = cmd.getLen(); // this is normally from "rows"
            Grouping grouping = new Grouping(searcher, result, cmd, cacheSecondPassSearch,
                    maxDocsPercentageToCache, groupingSpec.isMain());
            grouping.setSort(groupingSpec.getGroupSort()).setGroupSort(groupingSpec.getSortWithinGroup())
                    .setDefaultFormat(groupingSpec.getResponseFormat()).setLimitDefault(limitDefault)
                    .setDefaultTotalCount(defaultTotalCount)
                    .setDocsPerGroupDefault(groupingSpec.getGroupLimit())
                    .setGroupOffsetDefault(groupingSpec.getGroupOffset())
                    .setGetGroupedDocSet(groupingSpec.isTruncateGroups());

            if (groupingSpec.getFields() != null) {
                for (String field : groupingSpec.getFields()) {
                    grouping.addFieldCommand(field, rb.req);
                }
            }

            if (groupingSpec.getFunctions() != null) {
                for (String groupByStr : groupingSpec.getFunctions()) {
                    grouping.addFunctionCommand(groupByStr, rb.req);
                }
            }

            if (groupingSpec.getQueries() != null) {
                for (String groupByStr : groupingSpec.getQueries()) {
                    grouping.addQueryCommand(groupByStr, rb.req);
                }
            }

            if (rb.doHighlights || rb.isDebug() || params.getBool(MoreLikeThisParams.MLT, false)) {
                // we need a single list of the returned docs
                cmd.setFlags(SolrIndexSearcher.GET_DOCLIST);
            }

            grouping.execute();
            if (grouping.isSignalCacheWarning()) {
                rsp.add("cacheWarning", String.format(Locale.ROOT,
                        "Cache limit of %d percent relative to maxdoc has exceeded. Please increase cache size or disable caching.",
                        maxDocsPercentageToCache));
            }
            rb.setResult(result);

            if (grouping.mainResult != null) {
                ResultContext ctx = new ResultContext();
                ctx.docs = grouping.mainResult;
                ctx.query = null; // TODO? add the query?
                rsp.add("response", ctx);
                rsp.getToLog().add("hits", grouping.mainResult.matches());
            } else if (!grouping.getCommands().isEmpty()) { // Can never be empty since grouping.execute() checks for this.
                rsp.add("grouped", result.groupedResults);
                rsp.getToLog().add("hits", grouping.getCommands().get(0).getMatches());
            }
            return;
        } catch (ParseException e) {
            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);
        }
    }

    // normal search result
    searcher.search(result, cmd);
    rb.setResult(result);
    log.info("result is " + result.toString());

    ResultContext ctx = new ResultContext();
    ctx.docs = rb.getResults().docList;
    ctx.query = rb.getQuery();
    rsp.add("response", ctx);
    rsp.add("testpath", "hello response path");
    log.info("rsponse values :" + rsp.getValues().toString());
    rsp.getToLog().add("hits", 100000);

    log.info("ctx.docs is " + ctx.docs.toString());
    log.info("ctx is " + ctx.toString());
    testfuciton();
    doFieldSortValues(rb, searcher);
    doPrefetch(rb);
}

From source file:org.apache.solr.handler.component.QueryComponent.java

License:Apache License

/**
 * Actually run the query//from   w w w.j ava  2s .  com
 */
@Override
public void process(ResponseBuilder rb) throws IOException {
    SolrQueryRequest req = rb.req;
    SolrQueryResponse rsp = rb.rsp;
    SolrParams params = req.getParams();
    if (!params.getBool(COMPONENT_NAME, true)) {
        return;
    }
    SolrIndexSearcher searcher = req.getSearcher();

    if (rb.getQueryCommand().getOffset() < 0) {
        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "'start' parameter cannot be negative");
    }

    // -1 as flag if not set.
    long timeAllowed = (long) params.getInt(CommonParams.TIME_ALLOWED, -1);

    // Optional: This could also be implemented by the top-level searcher sending
    // a filter that lists the ids... that would be transparent to
    // the request handler, but would be more expensive (and would preserve score
    // too if desired).
    String ids = params.get(ShardParams.IDS);
    if (ids != null) {
        SchemaField idField = searcher.getSchema().getUniqueKeyField();
        List<String> idArr = StrUtils.splitSmart(ids, ",", true);
        int[] luceneIds = new int[idArr.size()];
        int docs = 0;
        for (int i = 0; i < idArr.size(); i++) {
            int id = req.getSearcher()
                    .getFirstMatch(new Term(idField.getName(), idField.getType().toInternal(idArr.get(i))));
            if (id >= 0)
                luceneIds[docs++] = id;
        }

        DocListAndSet res = new DocListAndSet();
        res.docList = new DocSlice(0, docs, luceneIds, null, docs, 0);
        if (rb.isNeedDocSet()) {
            // TODO: create a cache for this!
            List<Query> queries = new ArrayList<Query>();
            queries.add(rb.getQuery());
            List<Query> filters = rb.getFilters();
            if (filters != null)
                queries.addAll(filters);
            res.docSet = searcher.getDocSet(queries);
        }
        rb.setResults(res);

        ResultContext ctx = new ResultContext();
        ctx.docs = rb.getResults().docList;
        ctx.query = null; // anything?
        rsp.add("response", ctx);
        return;
    }

    SolrIndexSearcher.QueryCommand cmd = rb.getQueryCommand();
    cmd.setTimeAllowed(timeAllowed);
    SolrIndexSearcher.QueryResult result = new SolrIndexSearcher.QueryResult();

    //
    // grouping / field collapsing
    //
    GroupingSpecification groupingSpec = rb.getGroupingSpec();
    if (groupingSpec != null) {
        try {
            boolean needScores = (cmd.getFlags() & SolrIndexSearcher.GET_SCORES) != 0;
            if (params.getBool(GroupParams.GROUP_DISTRIBUTED_FIRST, false)) {
                CommandHandler.Builder topsGroupsActionBuilder = new CommandHandler.Builder()
                        .setQueryCommand(cmd).setNeedDocSet(false) // Order matters here
                        .setIncludeHitCount(true).setSearcher(searcher);

                for (String field : groupingSpec.getFields()) {
                    topsGroupsActionBuilder.addCommandField(new SearchGroupsFieldCommand.Builder()
                            .setField(searcher.getSchema().getField(field))
                            .setGroupSort(groupingSpec.getGroupSort())
                            .setTopNGroups(cmd.getOffset() + cmd.getLen())
                            .setIncludeGroupCount(groupingSpec.isIncludeGroupCount()).build());
                }

                CommandHandler commandHandler = topsGroupsActionBuilder.build();
                commandHandler.execute();
                SearchGroupsResultTransformer serializer = new SearchGroupsResultTransformer(searcher);
                rsp.add("firstPhase", commandHandler.processResult(result, serializer));
                rsp.add("totalHitCount", commandHandler.getTotalHitCount());
                rb.setResult(result);
                return;
            } else if (params.getBool(GroupParams.GROUP_DISTRIBUTED_SECOND, false)) {
                CommandHandler.Builder secondPhaseBuilder = new CommandHandler.Builder().setQueryCommand(cmd)
                        .setTruncateGroups(
                                groupingSpec.isTruncateGroups() && groupingSpec.getFields().length > 0)
                        .setSearcher(searcher);

                for (String field : groupingSpec.getFields()) {
                    String[] topGroupsParam = params
                            .getParams(GroupParams.GROUP_DISTRIBUTED_TOPGROUPS_PREFIX + field);
                    if (topGroupsParam == null) {
                        topGroupsParam = new String[0];
                    }

                    List<SearchGroup<BytesRef>> topGroups = new ArrayList<SearchGroup<BytesRef>>(
                            topGroupsParam.length);
                    for (String topGroup : topGroupsParam) {
                        SearchGroup<BytesRef> searchGroup = new SearchGroup<BytesRef>();
                        if (!topGroup.equals(TopGroupsShardRequestFactory.GROUP_NULL_VALUE)) {
                            searchGroup.groupValue = new BytesRef(
                                    searcher.getSchema().getField(field).getType().readableToIndexed(topGroup));
                        }
                        topGroups.add(searchGroup);
                    }

                    secondPhaseBuilder.addCommandField(new TopGroupsFieldCommand.Builder()
                            .setField(searcher.getSchema().getField(field))
                            .setGroupSort(groupingSpec.getGroupSort())
                            .setSortWithinGroup(groupingSpec.getSortWithinGroup())
                            .setFirstPhaseGroups(topGroups)
                            .setMaxDocPerGroup(groupingSpec.getGroupOffset() + groupingSpec.getGroupLimit())
                            .setNeedScores(needScores).setNeedMaxScore(needScores).build());
                }

                for (String query : groupingSpec.getQueries()) {
                    secondPhaseBuilder.addCommandField(new QueryCommand.Builder()
                            .setDocsToCollect(groupingSpec.getOffset() + groupingSpec.getLimit())
                            .setSort(groupingSpec.getGroupSort()).setQuery(query, rb.req).setDocSet(searcher)
                            .build());
                }

                CommandHandler commandHandler = secondPhaseBuilder.build();
                commandHandler.execute();
                TopGroupsResultTransformer serializer = new TopGroupsResultTransformer(rb);
                rsp.add("secondPhase", commandHandler.processResult(result, serializer));
                rb.setResult(result);
                return;
            }

            int maxDocsPercentageToCache = params.getInt(GroupParams.GROUP_CACHE_PERCENTAGE, 0);
            boolean cacheSecondPassSearch = maxDocsPercentageToCache >= 1 && maxDocsPercentageToCache <= 100;
            Grouping.TotalCount defaultTotalCount = groupingSpec.isIncludeGroupCount()
                    ? Grouping.TotalCount.grouped
                    : Grouping.TotalCount.ungrouped;
            int limitDefault = cmd.getLen(); // this is normally from "rows"
            Grouping grouping = new Grouping(searcher, result, cmd, cacheSecondPassSearch,
                    maxDocsPercentageToCache, groupingSpec.isMain());
            grouping.setSort(groupingSpec.getGroupSort()).setGroupSort(groupingSpec.getSortWithinGroup())
                    .setDefaultFormat(groupingSpec.getResponseFormat()).setLimitDefault(limitDefault)
                    .setDefaultTotalCount(defaultTotalCount)
                    .setDocsPerGroupDefault(groupingSpec.getGroupLimit())
                    .setGroupOffsetDefault(groupingSpec.getGroupOffset())
                    .setGetGroupedDocSet(groupingSpec.isTruncateGroups());

            if (groupingSpec.getFields() != null) {
                for (String field : groupingSpec.getFields()) {
                    grouping.addFieldCommand(field, rb.req);
                }
            }

            if (groupingSpec.getFunctions() != null) {
                for (String groupByStr : groupingSpec.getFunctions()) {
                    grouping.addFunctionCommand(groupByStr, rb.req);
                }
            }

            if (groupingSpec.getQueries() != null) {
                for (String groupByStr : groupingSpec.getQueries()) {
                    grouping.addQueryCommand(groupByStr, rb.req);
                }
            }

            if (rb.doHighlights || rb.isDebug() || params.getBool(MoreLikeThisParams.MLT, false)) {
                // we need a single list of the returned docs
                cmd.setFlags(SolrIndexSearcher.GET_DOCLIST);
            }

            grouping.execute();
            if (grouping.isSignalCacheWarning()) {
                rsp.add("cacheWarning", String.format(Locale.ROOT,
                        "Cache limit of %d percent relative to maxdoc has exceeded. Please increase cache size or disable caching.",
                        maxDocsPercentageToCache));
            }
            rb.setResult(result);

            if (grouping.mainResult != null) {
                ResultContext ctx = new ResultContext();
                ctx.docs = grouping.mainResult;
                ctx.query = null; // TODO? add the query?
                rsp.add("response", ctx);
                rsp.getToLog().add("hits", grouping.mainResult.matches());
            } else if (!grouping.getCommands().isEmpty()) { // Can never be empty since grouping.execute() checks for this.
                rsp.add("grouped", result.groupedResults);
                rsp.getToLog().add("hits", grouping.getCommands().get(0).getMatches());
            }
            return;
        } catch (SyntaxError e) {
            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);
        }
    }

    // normal search result
    searcher.search(result, cmd);
    rb.setResult(result);

    ResultContext ctx = new ResultContext();
    ctx.docs = rb.getResults().docList;
    ctx.query = rb.getQuery();
    rsp.add("response", ctx);
    rsp.getToLog().add("hits", rb.getResults().docList.matches());

    doFieldSortValues(rb, searcher);
    doPrefetch(rb);
}

From source file:org.apache.solr.search.grouping.distributed.command.GroupConverter.java

License:Apache License

static Collection<SearchGroup<BytesRef>> fromMutable(SchemaField field,
        Collection<SearchGroup<MutableValue>> values) {
    if (values == null) {
        return null;
    }/* ww  w  .ja v  a2  s  . c  o m*/
    FieldType fieldType = field.getType();
    List<SearchGroup<BytesRef>> result = new ArrayList<>(values.size());
    for (SearchGroup<MutableValue> original : values) {
        SearchGroup<BytesRef> converted = new SearchGroup<BytesRef>();
        converted.sortValues = original.sortValues;
        if (original.groupValue.exists) {
            BytesRefBuilder binary = new BytesRefBuilder();
            fieldType.readableToIndexed(original.groupValue.toString(), binary);
            converted.groupValue = binary.get();
        } else {
            converted.groupValue = null;
        }
        result.add(converted);
    }
    return result;
}

From source file:org.apache.solr.search.grouping.distributed.command.GroupConverter.java

License:Apache License

static Collection<SearchGroup<MutableValue>> toMutable(SchemaField field,
        Collection<SearchGroup<BytesRef>> values) {
    FieldType fieldType = field.getType();
    List<SearchGroup<MutableValue>> result = new ArrayList<>(values.size());
    for (SearchGroup<BytesRef> original : values) {
        SearchGroup<MutableValue> converted = new SearchGroup<MutableValue>();
        converted.sortValues = original.sortValues; // ?
        TrieField.TrieTypes type = ((TrieField) fieldType).getType();
        final MutableValue v;
        switch (type) {
        case INTEGER:
            MutableValueInt mutableInt = new MutableValueInt();
            if (original.groupValue == null) {
                mutableInt.value = 0;/*w w  w.  j a  v a2s .c  o m*/
                mutableInt.exists = false;
            } else {
                mutableInt.value = (Integer) fieldType.toObject(field, original.groupValue);
            }
            v = mutableInt;
            break;
        case FLOAT:
            MutableValueFloat mutableFloat = new MutableValueFloat();
            if (original.groupValue == null) {
                mutableFloat.value = 0;
                mutableFloat.exists = false;
            } else {
                mutableFloat.value = (Float) fieldType.toObject(field, original.groupValue);
            }
            v = mutableFloat;
            break;
        case DOUBLE:
            MutableValueDouble mutableDouble = new MutableValueDouble();
            if (original.groupValue == null) {
                mutableDouble.value = 0;
                mutableDouble.exists = false;
            } else {
                mutableDouble.value = (Double) fieldType.toObject(field, original.groupValue);
            }
            v = mutableDouble;
            break;
        case LONG:
            MutableValueLong mutableLong = new MutableValueLong();
            if (original.groupValue == null) {
                mutableLong.value = 0;
                mutableLong.exists = false;
            } else {
                mutableLong.value = (Long) fieldType.toObject(field, original.groupValue);
            }
            v = mutableLong;
            break;
        case DATE:
            MutableValueDate mutableDate = new MutableValueDate();
            if (original.groupValue == null) {
                mutableDate.value = 0;
                mutableDate.exists = false;
            } else {
                mutableDate.value = ((Date) fieldType.toObject(field, original.groupValue)).getTime();
            }
            v = mutableDate;
            break;
        default:
            throw new AssertionError();
        }
        converted.groupValue = v;
        result.add(converted);
    }
    return result;
}

From source file:org.apache.solr.search.grouping.distributed.shardresultserializer.SearchGroupsResultTransformer.java

License:Apache License

/**
 * {@inheritDoc}/*  ww w.  j av a  2 s.c o  m*/
 */
@Override
public Map<String, Pair<Integer, Collection<SearchGroup<BytesRef>>>> transformToNative(
        NamedList<NamedList> shardResponse, Sort groupSort, Sort sortWithinGroup, String shard) {
    Map<String, Pair<Integer, Collection<SearchGroup<BytesRef>>>> result = new HashMap<String, Pair<Integer, Collection<SearchGroup<BytesRef>>>>();
    for (Map.Entry<String, NamedList> command : shardResponse) {
        List<SearchGroup<BytesRef>> searchGroups = new ArrayList<SearchGroup<BytesRef>>();
        NamedList topGroupsAndGroupCount = command.getValue();
        @SuppressWarnings("unchecked")
        NamedList<List<Comparable>> rawSearchGroups = (NamedList<List<Comparable>>) topGroupsAndGroupCount
                .get("topGroups");
        if (rawSearchGroups != null) {
            for (Map.Entry<String, List<Comparable>> rawSearchGroup : rawSearchGroups) {
                SearchGroup<BytesRef> searchGroup = new SearchGroup<BytesRef>();
                searchGroup.groupValue = rawSearchGroup.getKey() != null ? new BytesRef(rawSearchGroup.getKey())
                        : null;
                searchGroup.sortValues = rawSearchGroup.getValue()
                        .toArray(new Comparable[rawSearchGroup.getValue().size()]);
                searchGroups.add(searchGroup);
            }
        }

        Integer groupCount = (Integer) topGroupsAndGroupCount.get("groupCount");
        result.put(command.getKey(),
                new Pair<Integer, Collection<SearchGroup<BytesRef>>>(groupCount, searchGroups));
    }
    return result;
}