如果我正在修改术语,请原谅我,但是我无法让ES以对我的应用程序有意义的方式对结果进行评分。
我正在使用几个简单字段索引成千上万的用户,以及可能有数百个嵌套在索引中的每个用户的子对象(即 Book - > Pages 数据模型)。发送到索引的JSON如下所示:
user_id: 1
full_name: First User
username: firstymcfirsterton
posts:
id: 2
title: Puppies are Awesome
tags:
- dog house
- dog supplies
- dogs
- doggies
- hot dogs
- dog lovers
user_id: 2
full_name: Second User
username: seconddude
posts:
id: 3
title: Dogs are the best
tags:
- dog supperiority
- dog
id: 4
title: Why dogs eat?
tags:
- dog diet
- canines
id: 5
title: Who let the dogs out?
tags:
- dogs
- terrible music
标签是“标签”类型,使用“关键字”分析器,并提升10.标题不会提升。
当我搜索“dog”时,第一个用户的得分高于第二个用户。我假设这必须使用第一个用户的tf-idf更高。但是在我的应用程序中,理想情况下获得该术语命中的用户的帖子数量会更多。
我尝试按帖子数量进行排序,但如果用户有很多帖子,这会产生垃圾结果。基本上我想按照独特的帖子点击次数进行排序,这样有更多帖子点击的用户会上升到最高位置。
我将如何做到这一点。有什么想法吗?
答案 0 :(得分:2)
首先,我同意@karmi和@Zach的意见,通过匹配帖子来弄清楚你的意思是很重要的。为简单起见,我假设一个匹配的帖子在其中的某个地方有一个单词“dog”,我们没有使用关键字分析器来对标签进行匹配并提升更多的乐趣。
如果我理解你的问题,你想根据相关帖子的数量订购用户。这意味着您需要搜索帖子以查找相关帖子,然后将此信息用于您的用户查询。只有当帖子被单独索引时才有可能,这意味着帖子必须是子文档或嵌套字段。
假设帖子是子文档,我们可以像这样对数据进行原型设计:
curl -XPOST 'http://localhost:9200/test-idx' -d '{
"settings" : {
"number_of_shards" : 1,
"number_of_replicas" : 0
},
"mappings" : {
"user" : {
"_source" : { "enabled" : true },
"properties" : {
"full_name": { "type": "string" },
"username": { "type": "string" }
}
},
"post" : {
"_parent" : {
"type" : "user"
},
"properties" : {
"title": { "type": "string"},
"tags": { "type": "string", "boost": 10}
}
}
}
}' && echo
curl -XPUT 'http://localhost:9200/test-idx/user/1' -d '{
"full_name": "First User",
"username": "firstymcfirsterton"
}' && echo
curl -XPUT 'http://localhost:9200/test-idx/user/2' -d '{
"full_name": "Second User",
"username": "seconddude"
}' && echo
#Posts of the first user
curl -XPUT 'http://localhost:9200/test-idx/post/1?parent=1' -d '{
"title": "Puppies are Awesome",
"tags": ["dog house", "dog supplies", "dogs", "doggies", "hot dogs", "dog lovers", "dog"]
}' && echo
curl -XPUT 'http://localhost:9200/test-idx/post/2?parent=1' -d '{
"title": "Cats are Awesome too",
"tags": ["cat", "cat supplies", "cats"]
}' && echo
curl -XPUT 'http://localhost:9200/test-idx/post/3?parent=1' -d '{
"title": "One fine day with a woof and a purr",
"tags": ["catdog", "cartoons"]
}' && echo
#Posts of the second user
curl -XPUT 'http://localhost:9200/test-idx/post/4?parent=2' -d '{
"title": "Dogs are the best",
"tags": ["dog supperiority", "dog"]
}' && echo
curl -XPUT 'http://localhost:9200/test-idx/post/5?parent=2' -d '{
"title": "Why dogs eat?",
"tags": ["dog diet", "canines"]
}' && echo
curl -XPUT 'http://localhost:9200/test-idx/post/6?parent=2' -d '{
"title": "Who let the dogs out?",
"tags": ["dogs", "terrible music"]
}' && echo
curl -XPOST 'http://localhost:9200/test-idx/_refresh' && echo
我们可以使用Top Children Query查询这些数据。 (或者在嵌套字段的情况下,我们可以使用Nested Query)
获得类似的结果curl 'http://localhost:9200/test-idx/user/_search?pretty=true' -d '{
"query": {
"top_children" : {
"type": "post",
"query" : {
"bool" : {
"should": [
{ "text" : { "title" : "dog" } },
{ "text" : { "tags" : "dog" } }
]
}
},
"score" : "sum"
}
}
}' && echo
此查询将首先返回第一个用户,因为来自匹配标记的巨大提升因子。所以,它可能看起来不像你想要的,但有一些简单的方法来修复它。首先,我们可以减少标签字段的提升因子。 10对于可以重复多次的场来说是非常大的因素。或者,我们可以修改查询以完全忽略子命中的分数,并使用最匹配的子文档的数量作为分数:
curl 'http://localhost:9200/test-idx/user/_search?pretty=true' -d '{
"query": {
"top_children" : {
"type": "post",
"query" : {
"constant_score" : {
"query" : {
"bool" : {
"should": [
{ "text" : { "title" : "dog" } },
{ "text" : { "tags" : "dog" } }
]
}
}
}
},
"score" : "sum"
}
}
}' && echo