【发布时间】:2019-09-22 06:47:05
【问题描述】:
我需要一种方法来匹配最接近的弹性搜索文档编号。
我想使用弹性搜索来过滤可量化的属性,并且已经能够使用 range 查询来实现硬限制,接受跳过该结果集之外的结果。我希望获得与多个过滤器匹配的最接近的结果。
const query = {
query: {
bool: {
should: [
{
range: {
gte: 5,
lte: 15
}
},
{
range: {
gte: 1979,
lte: 1989
}
}
]
}
}
}
const results = await client.search({
index: 'test',
body: query
})
假设我有一些包含年份和销售额的文件。在 sn-p 中是如何在 javascript 中完成的一个小例子。它遍历整个列表并计算一个分数,然后根据该分数对它们进行排序,绝不会过滤掉结果,它们只是按相关性组织。
const data = [
{ "item": "one", "year": 1980, "sales": 20 },
{ "item": "two", "year": 1982, "sales": 12 },
{ "item": "three", "year": 1986, "sales": 6 },
{ "item": "four", "year": 1989, "sales": 4 },
{ "item": "five", "year": 1991, "sales": 6 }
]
const add = (a, b) => a + b
const findClosestMatch = (filters, data) => {
const scored = data.map(item => ({
...item,
// add the score to a copy of the data
_score: calculateDifferenceScore(filters, item)
}))
// mutate the scored array by sorting it
scored.sort((a, b) => a._score.total - b._score.total)
return scored
}
const calculateDifferenceScore = (filters, item) => {
const result = Object.keys(filters).reduce((acc, x) => ({
...acc,
// calculate the absolute difference between the filter and data point
[x]: Math.abs(filters[x] - item[x])
}), {})
// sum the total diffences
result.total = Object.values(result).reduce(add)
return result
}
console.log(
findClosestMatch({ sales: 10, year: 1984 }, data)
)
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>
我试图在弹性搜索中实现相同的目标,但在使用 function_score 查询时没有运气。例如
const query = {
query: {
function_score: {
functions: [
{
linear: {
"year": {
origin: 1984,
},
"sales": {
origin: 10,
}
}
}
]
}
}
}
const results = await client.search({
index: 'test',
body: query
})
没有要搜索的文本,我只用它来按数字过滤,我做错了什么还是这不是弹性搜索的用途,还有更好的选择吗?
使用上述每个文档仍然有一个默认分数,我无法获得任何过滤器来对分数应用任何修饰符。
感谢您的帮助,感谢我对 elasticsearch 的新用户链接到文档的文章或区域!
【问题讨论】:
标签: javascript node.js elasticsearch