在用Elasticsearch制作的搜索引擎中,考虑用户点击结果项以提高文档分数的最佳解决方案是什么?
是否有任何工具或插件可以使用,或者应该从头开始编写?
预计该解决方案将像google一样考虑以下几点:
发布于 2017-01-18 10:24:12
如果您正在使用rails/ruby开发您的API,您可以查看搜索踢,它几乎可以完成这项工作,方法是使搜索解决方案更加智能,并且有更多的使用。
现在,如果您不是在rails上,或者您希望开发您自己的内部实现,下面是我的一些关于体系结构的建议。
让我们首先从基本概述、关键模块、缺点以及针对解决方案中这些缺点的架构进行调整。
您将需要
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。如果我已经有“雪”在我的元和新的查询与这个关键字,我将更新相同的元文档。
现在我想讨论的缺点,以及为什么我选择将它们保存在单独的数据库中,而不是将它们附加到elasticsearch文档.中。
我不想每次触发一个新的查询来更新弹性文档中的单击计数和视图计数时,由elasticsearch集群进行锤击,因为我知道,通过倒排索引合并,更新非常广泛。
现在,为了弥补这一缺点,我将有一个每日或双每日批处理工作,将这些元信息移植到每个文档的弹性。我将使用这个新的元信息重新构建整个集群,并将别名从旧索引移动到新索引,而不需要任何停机时间。
现在,要将此信息关联起来或添加到弹性文档中,我将使用父子文件关系来映射与此相关的关键字的弹性文档。
所以我的基本父文档和子文档看起来就像
父文档
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,我刚刚选择了一个非常简单的公式,为每个子句都提供了演示boost params,并且这个查询可以重构到更远的实现提前评分算法。
脚本评分功能在这里很重要,因为我首先根据该单亲文档的搜索关键字过滤子文档,然后使用脚本评分使用单击和视图计数来影响我的整体文档得分。
这是我想在我的项目中实现的一种解决方案,我愿意接受对我的解决方案的建议和改进。
请分享你的建议和改进。
希望这能帮上忙谢谢
https://stackoverflow.com/questions/41711961
复制相似问题