elasticsearch是一种分布式的搜索引擎,以文档的形式保存数据,提供强大的检索与分析工具。
对用户,数据以索引/类型/文档/属性的层级进行存储,并且提供了一套RESTful API与之进行交互:
/*
组织结构
megacorp 索引
employee 类型
1 文档
"first_name" 属性
*/
/*
交互方式
PUT 插入/更新
GET 请求
DELETE 删除
HEAD 是否存在
*/
PUT /megacorp/employee/1
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
在组织结构上,一个运行中的es实例称为一个节点,一组节点组成一个集群;文档保存在分片内,分片是一个底层的工作但愿,每个分片只保留部分数据,分片分散在各个节点,但每个节点都知道任意文档的位置,能够将我们的请求直接转发到对应节点
同时,es对主流语言都提供了客户端,支持主流语言的开发。
常用的推荐模型,都会将用户/物料用一个稠密向量表示,线上推理时,利用用户/物料余弦相似度进行快速的物料召回。es在7.3版本后提供了向量检索功能,支持利用余弦相似度对属性进行检索。
定义mappings,类似数据库中定义schema
put my_index
{
"mappings": {
"properties": {
"my_vector": {
"type": "dense_vector",
"dims": 4
},
"my_text" : {
"type" : "keyword"
}
}
}
}
插入数据,批量插入数据可以利用_bulk
接口
PUT my_index/my_doc/1
{
"my_text" : "text1",
"my_vector" : [1, 0, 0, 0]
}
PUT my_index/my_doc/2
{
"my_text" : "text2",
"my_vector" : [0.5, 0, 0.5, 0]
}
PUT my_index/my_doc/3
{
"my_text" : "text3",
"my_vector" : [0, 1, 0, 0]
}
PUT my_index/my_doc/4
{
"my_text" : "text4",
"my_vector" : [0, 0.5, 0, 0.5]
}
定义查询
GET _search
{
"query": {
"script_score": {
"query": {
"match_all": {}
},
"script": {
"source": "cosineSimilarity(params.queryVector, 'my_vector')+1.0",
"params": {
"queryVector": [0.5, 0, 0, 1]
}
}
}
}
}
在7.3版本前会结合faiss之类的向量检索工具一起使用
Elasticsearch: The Definitive Guide
GitHub - IBM/elasticsearch-spark-recommender
GitHub - lijoabraham/spark-playground/recommendation_system_spark_es