SolrQuery挖掘--单维度聚合分析

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 假期重新把之前在新浪博客里面的文字梳理了下,搬到这里。

单维度聚合分析,主要解决类似以下场景的问题 (1)同一个用户搜索输入关键词 (2)某个时间段内搜索词排行榜 (3)某些关键词联合出现情况 (4)IP\位置 维度下的关键词聚合情况 (5)其他任何参与搜索的单维度搜索请求统计 (6)平均命中率、hits=0、查询平均响应时间 ...... (7)新词发现(8)输入提示

单维度聚合分析

为什么选择搜索引擎

单维度聚合分析应该是各种分析统计中最为简单、直接。 对于主动搜索、被动搜索一体的应用场景,有登录和无登陆等统一兼顾。并且提供接口服务,按需返回维度信息,并且可以复用。 无疑采取搜索引擎,依赖搜索引擎的facet统计功能,最为直接、快捷、有效、低沉本。前提是对搜索引擎比较熟悉,否则光一个 搜索引擎就折腾死人了。

单维度聚合分析意义

单维度分析意义主要在掌握数据属性、用户属性、热点发现。 例如:某个产品上某个用户一段时间搜索词聚合,然后对聚合词语义分析,将可以分析出该用户的某些历史偏好、行为特征、消费 倾向、社区角色等。 例如:一段时间内产品上用户在搜什么,那些是热点词,是否与运营活动相关,是否是产品的重点词范畴等。 例如:将关键词、时间、产品倒排起来,那么就可以知道任何时间段内,具体产品活跃的关键词分布,间接知晓产品的语义集合例如:将关键词、用户、时间倒排起来,那么很容易知晓那些词偏女性、那些词偏男性、那些词中性,用户那个时候搜的多、是那些词 例如:将关键词、排序、翻页、命中倒排起来,那么很容易发现点击热点、超时分析等。 。。。。 太多了

陷阱

大家都关注结果去了,没有人喜欢过程,尤其是周期性、长期的过程。在淘宝上成交量、客单价为主题的大环境,任何和交易不相关 、任何不能直接影响交易、任何只是提升用户细微体验等等工作,都是一个弱势需求,甚至等于不是需求。 所以,技术即使实现,也不见得有人会关注、有人去用。KPI中不会因为用户体验而打分,KPI中不会因为改善排序效果而肯定。 因为本身这些不好评估效果,特别是短期内的效果。更本质的可能是这些无关交易

单维度聚合关键问题

维度的选择

既然是单维度聚合,那么维度的选择就非常重要了。这个需要不是技术一方面说的算,更多的依赖业务。 而往往习惯了运营为主、人肉、经验为主的 淘宝居多业务,对交易之位的属性关注度明显的不在意。 也甚至出现,计算出来的结果会在 白名单、黑名单过滤下,面目全非。 通常基本的维度不可少:时间、业务、人、关键词等。也即时间、地点、人物、事件。

格式化

输入就是线上日志,输出就是格式化文档或者倒排索引结构。 在输入和输出之间就是转换。转换的过程其实非常麻烦的问题,只看一端只觉得问题很easy! 麻烦之处:

(1)提取规则

日志总是有许多莫名其妙的格式、内容、乱码。很难有一个100%的规则,满足所有请求日志。 即使有,也很难很容易的扩展到其他应用。例如solr 日志格式是有规律的,但是用户内容不一定有规律。 基于文本标签提取,自然会遇到内容的标签问题。提取完毕之后,schema结构具体应用是不一样的。

(2)提取速度

越精细越耗时,并且java String对象处理起来比较方便,却速度上远远低于char,而char处理不是很方便。 对应solr query log 还是建议采取char为主、StringBuidler为核心变量。

(3)适应性

一开始都是追求100%解析通过,实际总有那么一些内容,搅合常规处理方法。为了适应这些非常规的请求, 往往会将之前的处理规则打破或者添加更多条件,然后整体性能突然下降。建议:能处理的快速处理,不能处理的 单独输入到一个文本,对于这些非常规的特殊处理。

单维度聚合实现样例

对于终搜 solr 日志 输入 2012-08-09 14:50:33,396 INFO [org.apache.solr.core.SolrCore] - [search4product-0] webapp=null path=/select params={q=+supplier_id% 3A649289&sort=weight1+desc&rows=30&start=0&facet=true &facet.field=cat_path&hl.usePhraseHighlighter=false&echoParams=explicit&hl=true &hl.fl=title&hl.requireFieldMatch=true&hl.simple.pre=&hl.simple.post=&hl.snippets=3&hl.fragsize=2000&timeAllowed=2500} hits=1762 status=0 QTime=123

解码 2012-08-09 14:50:33,396 INFO [org.apache.solr.core.SolrCore] - [search4product-0] webapp=null path=/select params={q=+supplier_id:649289&sort=weight1 desc&rows=30&start=0&facet=true&facet.field=cat_path&hl.usePhraseHighlighter=false &echoParams=explicit&hl=true&hl.fl=title&hl.requireFieldMatch=true&hl.simple.pre=&hl.simple.post=&hl.snippets=3&hl.fragsize=2000&timeAllowed=2500} hits=1762 status=0 QTime=123

public class QueryRowToStructureQuery {  
//private static String splitTag="#&";
protected static Log log = LogFactory.getLog( QueryRowToStructureQuery.class);
public static String doParseDemoV2(String inputStr) {
if (inputStr == null) return null;
// long start= System.nanoTime();
StringBuilder sb = new StringBuilder();
sb.append(inputStr.subSequence(0, 10)).append("T").append(inputStr.subSequence(11, 19)).append("Z").append( DefaultParams.SPLITTAG );//time  
char[] chars = inputStr.toCharArray();  
int i = 64; int tep = i; while (chars[i] != ']') i++;
sb.append(inputStr.subSequence(tep, i)).append(DefaultParams.SPLITTAG);// searviceName // extract  
i = getItem(chars, i, sb);//
递归抽取查询串  
String[] temp=inputStr.subSequence(i + 2, inputStr.length()).toString().trim().split(" ");if(temp[0].contains("hits")){
sb.append(temp[0].replaceAll("=", ":")).append(DefaultParams.SPLITTAG);sb.append(temp[2].replaceAll("=", ":")).append("\r\n");// hits status QTime // System.out.println("doParseDemoV2_timeCost="+(System.nanoTime()-start)); // System.out.println(sb.toString());
return sb.toString(); }
else{ log.error(inputStr);//
针对无法处理或者处理格式不对的抛出异常
return null; } }    

private static int getItem(char[] chars, int i, StringBuilder sb) {
while (chars[i] != '{') { i++; }  
boolean changed = true;
int pos = 0;
while (true && chars[i] != '}') {
i++; if (changed) {
pos = i; changed = false; }
// System.out.println(chars[i]); // int deep=1;
boolean stop = true;
if (chars[i] == '&') { StringBuilder sbTemp = new StringBuilder();
for (int t = pos; t < i; t++) if (chars[t] == '(' || chars[t] == ')') { } elsesbTemp.append(chars[t]); changed = true; String temp = sbTemp.toString();
// if (temp.getBytes().length != temp.length()) // sb.append("CW_").append(temp.trim()).append(DefaultParams.SPLITTAG); // else
if (temp.contains(":")) sb.append(temp.trim()).append(DefaultParams.SPLITTAG);
else if (temp.contains("sort")) sb.append(temp.trim().replaceAll("=", ":")).append(DefaultParams.SPLITTAG); else ; // System.out.println(sbTemp.toString()); }  
if (chars[i] == '+') { if (changed) {
pos = i; i++; changed = false; } while (true )
{ if (chars[i] == '+' || chars[i] == '&' || chars.length < i) break; else i++; }
StringBuilder sbTemp = new StringBuilder();
for (int t = pos; t < i; t++) {
if (chars[t] == '(' || chars[t] == ')' ) { } else sbTemp.append(chars[t]);   }
changed = true; String temp = sbTemp.toString(); // System.out.println(temp); // if (temp.getBytes().length != temp.length()) // sb.append("CW_").append(temp.trim()).append(DefaultParams.SPLITTAG); // else if(temp.contains(":")) sb.append(temp.trim()).append(DefaultParams.SPLITTAG);
else if (temp.contains("sort")) sb.append(temp.trim().replaceAll("=", ":")).append(DefaultParams.SPLITTAG); else ; } } return i; }

提取输出2012-08-09T14:50:33Z#&search4product-0#&supplier_id:649289#&sort:weight1 desc#&hits:1762#&QTime:123 构建solr document

public static AddUpdateCommand generateAddCommand(String query, IndexSchema schema) {AddUpdateCommand addCmd = new AddUpdateCommand();
addCmd.allowDups = false; addCmd.overwriteCommitted = true;
addCmd.overwritePending = true;
SolrInputDocument solrDoc = new SolrInputDocument();
solrDoc.clear();   //solrDoc.setDocumentBoost(DEFAULT_DOCUMENT_BOOST);
String[] items = query.split( DefaultParams.SPLITTAG ); //logger.warn( query );  solrDoc.addField("reqtime", items[0]);
solrDoc.addField("sername", items[1]);  
for (int i=2;i<items.length; i++) {
String[] keyPair= items[i].split(":");
if ( schema.getFieldOrNull( keyPair[0].toString()) == null ) {
//
忽略多余的字段,没有在schema.xml中配置的字段
continue; }
if ( keyPair[1] == null ||(keyPair[1] != null && (" ").equals(keyPair[1])) ) { continue; }solrDoc.addField(keyPair[0], keyPair[1]);
}
addCmd.solrDoc = solrDoc;
try{
addCmd.doc = DocumentBuilder.toDocument( solrDoc, schema );
}
catch(Exception e){
logger.error(solrDoc, e); }
return addCmd; }

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
4月前
|
SQL 缓存 数据挖掘
数据平台问题之复合指标生成中维度能力如何处理
数据平台问题之复合指标生成中维度能力如何处理
|
7月前
|
数据挖掘 索引
使用 DataFrame 进行数据聚合与透视:洞察数据深层结构
【5月更文挑战第19天】DataFrame 提供了聚合和透视功能,便于数据分析。通过`groupby`和`agg`计算类别统计信息,如`sum`和`mean`,揭示数据模式。使用`pivot_table`重新排列数据,展示清晰结构。多维度透视和按时间聚合进一步增强分析能力。这些工具帮助我们理解复杂数据,挖掘隐藏规律,为决策提供依据。利用DataFrame进行数据深层分析,解锁数据价值,开启数据探索之旅。
82 2
|
存储 数据挖掘 关系型数据库
数仓学习---6、数据仓库概述、 数据仓库建模概述、维度建模理论之事实表、维度建模理论之维度表
数仓学习---6、数据仓库概述、 数据仓库建模概述、维度建模理论之事实表、维度建模理论之维度表
|
7月前
|
数据挖掘 数据库
离线数仓6.0--- 数据仓库 ER模型-范式理论,维度模型、维度建模理论之事实表、维度建模理论之维度表
离线数仓6.0--- 数据仓库 ER模型-范式理论,维度模型、维度建模理论之事实表、维度建模理论之维度表
301 0
|
数据挖掘
怎么理解数据分析、维度和指标?
怎么理解数据分析、维度和指标?
|
DataWorks
维度建模实践一例 (一) 维度还是事实
成本和单价是产品的维度还是事实表中的事实?来看看我对这个问题的思考与分享吧。
498 0
维度建模实践一例  (一) 维度还是事实
|
人工智能 自然语言处理 数据管理
分析的四个维度
分析的四个维度
|
DataWorks
维度建模实践一例 (一) 维度还是事实
成本和单价是产品的维度还是事实表中的事实?来看看我对这个问题的思考与分享吧。
360 0
维度建模实践一例 (一) 维度还是事实
|
机器学习/深度学习 数据挖掘
数据分析:5个数据相关性指标
相似性度量是许多数据分析和机器学习任务中的重要工具,使我们能够比较和评估不同数据片段之间的相似性。有许多不同的指标可用,每个指标各有利弊,适用于不同的数据类型和任务。
287 0
|
SQL 分布式计算 大数据
聚合操作_多维聚合_cubeSQL | 学习笔记
快速学习聚合操作_多维聚合_cubeSQL
122 0
聚合操作_多维聚合_cubeSQL | 学习笔记