1

I have documents like

{id:1, name:foo, from: China}
{id:2, name:bar, from: USA}
{id:3, name:baz, from: Japan}
{id:4, name:foo, from: China}

Then I grouping these documents by from field.

And I want to get the top N country from which users come from.

I don't know how to sort by docs count of each group. Or is there a better way to do this.

4

3 回答 3

0

我不认为使用 Lucene 是实现您想要的最佳方式,但您可以迭代结果并在地图中收集每个国家/地区的计数:

final Map<String, Integer> country2count = new HashMap<String, Integer>();
    for (final ScoreDoc hit : hits) {
        final int docId = hit.doc;
        if (!reader.isDeleted(docId)) {
            // Get the document from docId
            final Document document = searcher.doc(docId);
            // Get the country
            final String country = document.get("from");

            if(country2count.containsKey(country)){
                int prevCount = country2count.get(country);
                country2count.put(country, ++prevCount);
            }else{
                country2count.put(country, 1);
            }
        }
    }

我建议您不要使用索引,而是使用简单的日志,而不是使用以下内容获取用户数量最多的国家/地区:

猫 id_name_from.log | awk '{打印 $3}' | 排序-k 3 | 唯一的-c | 排序-nrk 1

示例:保存为“id \t name \t from”的日志文件:

1   foo China
2   foo Usa
3   bar China
4   foo China
5   foo China
6   foo Usa
7   bar China
8   foo China
9   foo Usa

脚本:

cat log | awk '{print $3}' | sort | uniq -c | sort -nrk 1

结果:

6 China
3 Usa
于 2013-09-05T18:16:59.233 回答
0

也许你可以做一个sort这样的,new Sort(new SortField[]{new SortField("from", SortField.STRING), new SortField("id", SortField.INT)})

如果你有其他需求,你可以自己实现Collector,Lucene 会使用最小堆来收集结果,你可以使用一个树集来存储与from堆中每个元素相同的文档,在树集中你可以排序id

于 2013-09-05T03:11:36.460 回答
0
// Do a first pass (this is the "expensive" part)
String gField = "from";
Sort gSort = Sort.RELEVANCE;
int gOffset = 0;
int gLimit = 25;
TermFirstPassGroupingCollector firstCollector = new TermFirstPassGroupingCollector(...);
indexSearcher.search(query, firstCollector);
Collection<SearchGroup<BytesRef>> topGroups = firstCollector.getTopGroups(...);

//Do a second pass
Sort sortWithinGroup = new Sort(new SortField("WhateverYouWantToSortBy"...));
int offsetInGroup = 0;
int docsPerGroup = 1;
TermSecondPassGroupingCollector secondCollector = new TermSecondPassGroupingCollector(...);
indexSearcher.search(query, secondCollector);
TopGroups<BytesRef> results = secondCollector.getTopGroups(offsetInGroup);

// Do other stuff ...
于 2013-10-25T13:54:04.610 回答