Elasticsearch用户点击反馈
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch用户点击反馈相关的知识,希望对你有一定的参考价值。
在使用Elasticsearch制作的搜索引擎中,考虑用户对结果项的点击以提高具有更多用户展示次数的文档得分的最佳解决方案是什么?
有没有可以使用的工具或插件,还是应该从头开始编写?
预计解决方案将考虑以下谷歌:
- 每个文档的显示次数
- 用户点击文档的次数
- 用户搜索的查询(文档在特定查询中可能很重要,但在其他查询中不重要)
- ...
如果您正在使用rails / ruby开发API,那么您可以通过使用更多的搜索解决方案使搜索解决方案变得更加智能,来查看searchkick。
现在,如果您不在轨道上,或者您想开发自己的内部实施,那么这里有一些关于架构的建议。
首先介绍基本概述,关键模块,缺点并根据解决方案的缺点调整体系结构。
你会需要
1)评分算法,您可以在其中定义公式的公式,该公式将生成每个文档的分数。让我们考虑你提到的参数
a)没有时间显示每个文件b)没有点击文件的时间。 c)查询搜索的文档。
现在你还没有提到a)和b)如何适应当前的背景。我会假设一个更简单的,但如果你想建立一个真正先进的智能解决方案,我也会将a)b)与c)结合起来。例如 - 文档针对给定关键字出现的次数。像我一样,搜索“雪地靴”应该考虑这个(出现次数/无点击次数)仅适用于查询或多或少像“雪地靴”而不是所有情况。其中“雪地靴”可以被破坏为具有关键字顺序近似的以下元的关键字。
{
"keyword": "snow",
"document_ids": [3, 5, 6, 8],
"document_ids_views": [{
"doc_id": 3,
"views ": 110,
"clicks": 560
}, {
"doc_id": 5,
"views": 100,
"clicks": 78
}, {
"doc_id": 6,
"views": 100,
"clicks": 120
}, {
"doc_id": 3,
"views": 100,
"clicks": 465
}]
}
{
"keyword": "boots",
"document_ids": [3, 5, 6, 8],
"document_ids_views": [{
"doc_id": 3,
"views ": 100,
"clicks": 56
}, {
"doc_id": 5,
"views": 100,
"clicks": 78
}, {
"doc_id": 6,
"views": 100,
"clicks": 120
}, {
"doc_id": 3,
"views": 100,
"clicks": 465
}]
}
以上是存储在每个关键字的单独数据库中的聚合数据。
像这样我会在一个单独的数据存储区中每天建立一个统计数据的元数据,比方说mongo。如果我的meta中已经有“snow”,并且使用此关键字进入新查询,我将更新相同的元文档。
现在我想讨论一下缺点以及为什么我选择将它们保存在单独的数据库中,而不是将它们附加到elasticsearch文档中。
每次触发新查询以更新弹性文档中的点击计数和视图计数时,我都不想通过elasticsearch集群进行锤击,因为我知道更新对于反向索引合并非常I / O广泛。
现在为了弥补这个缺点,我将有一个每日或每日两次的批处理作业,以弹性方式将这些元信息移植到每个文档。我将使用这个新的元信息重建整个集群,并将别名从旧索引移动到新索引,而不会有任何停机时间。
现在要将此信息与弹性文档关联或添加,我将使用parent-child documents relationship将弹性文档与关联的关键字进行映射。
所以我的基本父文档和子文档可能看起来像
父文件
PUT /index/type/3
{
"name": "Reebok shoes",
"category": "snow boots",
"price": 120
}
儿童文件
PUT /index/type_meta/1?parent=3
{
"keyword": "boots",
"document_id": 3,
"doc_id": 3,
"views ": 100,
"clicks": 56
}
PUT /index/type_meta/1?parent=3
{
"keyword": "snow",
"document_id": 3,
"doc_id": 3,
"views ": 110,
"clicks": 560
}
上面的父子文档几乎解释了我如何构建每个文档的搜索统计信息的元数据。
到目前为止,我们已经构建了一个非常智能的解决方案来收集搜索统计数据的事件数据,并成功将它们与弹性的每个文档相关联
让我们开始在这里查看评分查询 -
我不会在这里设计得分算法,但我会更多地实现查询,该查询可以根据视图对文档进行评分,点击关联关键字以及与关键字相关。
现在我可以选择给名字中的比赛赋予更多的权重而不是类别。从你的用法观点来看,我都不会深入为你设计得分公式。
{
"query": {
"function_score": {
"query": {
"match_all": {}
},
"boost": "5",
"functions": [{
"filter": {
"match": {
"name": "snow"
}
},
"random_score": {},
"weight": 200
}, {
"filter": {
"match": {
"name": "boots"
}
},
"weight": 200
}, {
"filter": {
"match": {
"category": "snow"
}
},
"random_score": {},
"weight": 100
}, {
"filter": {
"match": {
"category": "boots"
}
},
"weight": 100
}, {
"filter": {
"query": {
"has_parent": {
"type": "type_meta",
"query": {
"match": {
"keyword": "snow"
}
}
}
}
},
"script_score": {
"script": {
"lang": "painless",
"inline": "_score + 20*doc['clicks'].value + 40 * doc['views].value"
}
}
}, {
"filter": {
"query": {
"has_parent": {
"type": "type_meta",
"query": {
"match": {
"keyword": "boots"
}
}
}
}
},
"script_score": {
"script": {
"lang": "painless",
"inline": "_score + 20*doc['clicks'].value + 40 * doc['views].value"
}
}
}],
"score_mode": "max",
"boost_mode": "multiply"
}
}
}
所以你可以使用像上面这样的查询simillar,我刚刚为每个子句选择了一个非常简单的带有demo boost params的公式,这个查询可以重构为实现提前计分算法。
脚本分数功能在这里很重要,因为我首先根据该单个父文档的搜索关键字过滤子文档,然后使用脚本分数来使用点击和查看计数来影响我的整体文档分数。
现在这是我希望在我的项目中实施的一种解决方案,我愿意接受我的解决方案的建议和改进。
请分享您的建议和改进。
希望这有助于谢谢
以上是关于Elasticsearch用户点击反馈的主要内容,如果未能解决你的问题,请参考以下文章
elasticsearch代码片段,及工具类SearchEsUtil.java
ElasticSearch学习问题记录——Invalid shift value in prefixCoded bytes (is encoded value really an INT?)(代码片段