我想知道,在将Postgres的全文搜索与Elasticsearch进行比较时,有实施全文搜索经验的人是否可以对我的奇怪结果有所了解。
我使用一对Rails应用程序来测试它们,每个都有相同的模型(但是有不同的宝石,用于pg测试的'textacular',用于es测试的'searchkick')和相同的测试数据:
# seeds.rb
def make_post(body)
{
title: 'A Post About Fruits',
body: body,
num_likes: 0
}
end
Post.destroy_all
Post.create([
make_post('I like apples.'),
make_post('I like bananas.'),
make_post('I like apples and bananas.'),
make_post('I like oranges.'),
make_post('I like.')
])
但是当我对它们进行大量搜索时,结果似乎对Postgres更有意义,有时候对Elasticsearch更有意义,并且它们在行为上经常相互矛盾。在下面的结果中,我列出了为每个搜索词返回的前两个帖子,或者一个帖子或零,如果这是所有返回的:
搜索:
'苹果':
PG: “我喜欢苹果。” “我喜欢苹果和香蕉。”
ES:
- '我喜欢苹果和香蕉。'
- '我喜欢苹果。'
醇>'香蕉':
PG: “我喜欢香蕉。” “我喜欢苹果和香蕉。”
ES: “我喜欢香蕉。” “我喜欢苹果和香蕉。”
'apples and':
PG: “我喜欢苹果。” “我喜欢苹果和香蕉。”
ES: “我喜欢苹果和香蕉。”
“苹果和香蕉”:PG: “我喜欢苹果和香蕉。”
ES: “我喜欢苹果和香蕉。”
'我喜欢苹果。':
PG: “我喜欢苹果。” “我喜欢苹果和香蕉。”
ES: “我喜欢苹果和香蕉。” “我喜欢苹果。”
'应用':
pg:没有结果
ES: “我喜欢苹果和香蕉。” “我喜欢苹果。”
'申请':
PG: “我喜欢苹果。” “我喜欢苹果和香蕉。”
ES: “我喜欢苹果和香蕉。” “我喜欢苹果。”
我不得不承认,这是默认设置,我没有调整或使用自定义查询语法(做AND vs OR等)。
答案 0 :(得分:2)
您从Elasticsearch获得了奇怪的结果,因为某些统计信息是在单个分片中计算的,而不是在整个索引中计算的。通常情况下这很好,因为大多数文档集都很大,但是当您在分片中只有一些文档时,这些统计数据并没有多大意义。在你的情况下,我认为有问题的统计数据是avgFieldLength,这有助于tfNorm得分。尝试使用一个分片创建一个新索引:
PUT /testindex
{
"settings": {
"index": {
"number_of_shards": 1
}
}
}
POST /testindex/doc/1
{
"body": "I like apples."
}
POST /testindex/doc/2
{
"body": "I like apples and bananas."
}
然后查询:
POST /testindex
{
"query": {
"query_string": {
"query": "apples"
}
}
然后你应该看到等级:
如果您想弄清楚排名发生了什么,可以使用说明:
POST /testindex
{
"explain": true,
"query": {
"query_string": {
"query": "apples"
}
}
所有这一切,你不应该期望postgres搜索排名与弹性搜索排名相匹配。 Elasticsearch使用标准化的tf-idf分数,而postgres不考虑文档频率或文档长度。有关详细信息,请参阅此问题:Does PostgreSQL use tf-idf?