如何用Solr统计二级索引搜索词执行频率并排序?
解决Solr二级索引统计高频搜索词Top10的问题
嘿,我来帮你搞定这个需求!你需要统计二级索引里搜索词的搜索频率并取Top10,这个用Solr的**Terms Facet(分面统计)**就能完美实现——你之前看的Term Vector确实不适用,因为它是统计单个文档内词的出现次数,而你要的是每一个搜索词作为搜索行为的总次数,本质是统计每个搜索词对应的文档数量(毕竟你的二级索引里每一条文档就是一次搜索记录)。
下面是具体的实现步骤:
1. 构造Solr查询参数
你只需要发送一个带分面统计的查询,就能直接得到每个搜索词的频率。这里假设你的搜索词字段名叫search_term,日期字段叫date(如果需要按时间范围过滤的话),示例查询URL如下:
http://your-solr-host:8983/solr/your-core/select?q=*:*&rows=0&facet=true&facet.field=search_term&facet.limit=10&facet.sort=count
参数解释:
q=*:*:匹配二级索引里的所有文档,如果需要按时间段统计,可改成类似q=date:[2018-01-01T00:00:00Z TO 2018-12-31T23:59:59Z]的过滤条件rows=0:不需要返回具体的搜索记录文档,只需要统计结果,这样能大幅提升查询性能facet=true:开启分面统计功能facet.field=search_term:指定要统计的字段为你的搜索词字段(替换成你实际的字段名)facet.limit=10:只返回频率最高的前10个搜索词facet.sort=count:按搜索频率从高到低排序
2. Solr返回的JSON结果示例
执行上面的查询后,你会得到类似这样的JSON响应:
{ "responseHeader": { "status": 0, "QTime": 15, "params": { "q": "*:*", "rows": "0", "facet": "true", "facet.field": "search_term", "facet.limit": "10", "facet.sort": "count" } }, "response": { "numFound": 5, "start": 0, "docs": [] }, "facet_counts": { "facet_queries": {}, "facet_fields": { "search_term": [ "term1", 2, "term3", 2, "term2", 1 ] }, "facet_ranges": {}, "facet_intervals": {}, "facet_heatmaps": {} } }
核心数据在facet_counts.facet_fields.search_term里,是一个交替排列的数组:索引偶数位是搜索词,奇数位是对应的搜索频率。
3. Java代码处理结果(用SolrJ客户端)
用Solr官方的Java客户端SolrJ来发送请求并解析结果非常方便,下面是完整的代码示例:
首先在你的项目中引入SolrJ依赖(以Maven为例,版本要和你的Solr服务器版本一致):
<dependency> <groupId>org.apache.solr</groupId> <artifactId>solr-solrj</artifactId> <version>8.11.2</version> <!-- 替换成你的Solr版本 --> </dependency>
然后编写Java代码:
import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.impl.HttpSolrClient; import org.apache.solr.client.solrj.response.QueryResponse; import java.util.List; import java.util.Map; public class HighFreqSearchTerms { public static void main(String[] args) { // 替换为你的Solr核心地址 String solrCoreUrl = "http://your-solr-host:8983/solr/your-core"; // 初始化Solr客户端(try-with-resources自动关闭资源) try (SolrClient solrClient = new HttpSolrClient.Builder(solrCoreUrl).build()) { SolrQuery query = new SolrQuery(); // 匹配所有文档,如需时间过滤可添加query.addFilterQuery("date:[开始时间 TO 结束时间]") query.setQuery("*:*"); query.setRows(0); // 不返回具体文档 query.setFacet(true); query.addFacetField("search_term"); // 替换为你的搜索词字段名 query.setFacetLimit(10); // 取Top10 query.setFacetSort(SolrQuery.FacetSort.COUNT); // 按频率降序 // 执行查询 QueryResponse response = solrClient.query(query); // 获取分面统计结果 Map<String, List<Object>> facetFields = response.getFacetFields(); List<Object> termCounts = facetFields.get("search_term"); // 输出你需要的格式 System.out.println("Search Term, Frequency"); for (int i = 0; i < termCounts.size(); i += 2) { String searchTerm = (String) termCounts.get(i); long frequency = (long) termCounts.get(i + 1); System.out.printf("%s,%d%n", searchTerm, frequency); } } catch (Exception e) { e.printStackTrace(); } } }
4. 额外注意事项
- 确保你的
search_term字段是不分词的字符串类型(比如Solr内置的string字段类型),这样才能统计完整的搜索词,而不是拆分后的单个词汇。字段定义示例:<field name="search_term" type="string" indexed="true" stored="true"/> - 如果需要更复杂的统计(比如按天/周分组统计高频词),可以结合Solr的
facet.range或者Stats Component来实现,但基础的Top10高频词用上面的方法就足够了。
内容的提问来源于stack exchange,提问作者Nirmalya
相关产品推荐
相关产品推荐

