两个实体:收集和产品。集合是Product的父级。
我需要通过产品的条款搜索,并显示每4个产品的集合。
藏品和产品可以部分匹配,但先要最好的匹配。如果匹配未满,则某些项具有优先权。
示例:搜索“color:red”和“Material:stone”需要首先显示红色石头,然后显示任何其他红色(这是关于收藏匹配和产品匹配)。
因此,所有这些都通过以下请求得到解决:
{
"query": {
"has_child": {
"type": "products",
"query": {
"bool": {
"should": [
{
"constant_score": {
"filter": {
"match_all": {}
},
"boost": 1
}
},
{
"constant_score": {
"filter": {
"terms": { "_name": "colors", "colors": [5] }
},
"boost": 1.2
}
},
{
"constant_score": {
"filter": {
"terms": { "_name": "materials", "productTypes": [6] }
},
"boost": 1
}
}
]
}
},
"score_mode": "max",
"inner_hits": {
"size": 4,
"sort": [
"_score"
]
}
}
},
"sort": [
"_score"
]
}
好了,现在麻烦来了。
需要按价格排序。作为ASC,作为DESC。价格是产品的属性。
需要按照匹配产品的价格进行排序,所以不能把价格移到集合中。需要按价格排序作为一个集合作为产品。按匹配产品的最小(或最大)价格排序的集合。
需要排序的价格只有100%匹配的产品(好吧,部分匹配可以排序太,但后)。我是说,排序必须像按分数,价格排序一样
例如,我想要得到的,按价格asc排序,[nn]表示部分匹配的产品:
Collection1
100 - 200 - 800 - [99]
Collection2
300 - 500 - [10] - [20]
Collection3
400 - 450 - 500 - [100]
我发现不支持按孩子排序。以及重新计算分数的建议。但我用分数来按匹配排序。我的尝试是
{
"query": {
"has_child": {
"type": "products",
"query": {
"function_score": {
"query": {
"bool": {
"should": [
... same query as above ...
]
}
},
"functions": [
{
"script_score": {
"script": "ceil(_score * 100) * 100000 + (99999 - doc['price'].value/100)",
"lang": "expression"
}
}
]
}
},
"score_mode": "max",
"inner_hits": {
"size": 4,
"sort": [
"_score",
{
"price": {
"order": "desc"
}
}
]
}
}
},
"sort": [
"_score"
]
}
但是我真的很困惑于我可以在答案中看到的结果。寻求帮助:)或者,也许,删除这个并创建一个嵌套索引?
UPD:发现分数不对。默认情况下,弹性组合script_score的得分和结果。所以score是ceil(_score*100)*100000+(99999-doc['price'].value/100)*_score
-这可能会打破想法,但很容易用function_score
的boost_mode
参数来修正。结果查询:
{
"query": {
"has_child": {
"type": "products",
"query": {
"function_score": {
"query": {
"bool": {
"should": [
... same query as above ...
]
}
},
"functions": [
{
"script_score": {
"script": "ceil((log10(_score)+10) * 100) * 100000 + (99999 - doc['price'].value)",
"lang": "expression"
}
}
],
"boost_mode": "replace"
}
},
"score_mode": "max",
"inner_hits": {
"size": 4,
"sort": [
"_score",
{
"price": {
"order": "desc"
}
}
]
}
}
},
"sort": [
"_score"
]
}
boost_mode=='replace
表示“使用函数结果作为分数”。另外,使用log10来确定_score中有多少位数字。对于按价格排序,DESC需要将公式更改为ceil((log10(_score)+10)*100)*100000+(doc['price'].value)
UPD2
公式CEIL((log10(_score)+10)*100)*100000+(99999-doc['price'].value)
返回100099952
,对于price48
,对于price50
(boost==1,queryNorm==1),因为有单个精度限制。
新公式ceil((log10(_score)+5)*100)*10000+(9999-ceil(log10(doc['price'].value)*1000))
-减少了score的位数,并从price转换为lg的price和减少了位数。欢迎反馈。
感谢您的分享,将最新公式更新为ceil((log10(_score+1)+5)*100)*10000+(9999-ceil(log10(doc['price'].value+1)*1000))
添加+1来得分,因为在某些情况下它返回如下错误:
"function score query returned an invalid score: -Infinity for doc: 4580"
更新:得到另一个错误:
"function score query returned an invalid score: NaN for doc: 1739"
将公式更改为ceil((log10(_score+1)+5)*100)*10000+(9999-ceil(log10(doc['price'].value+1)*1000))
将+1添加到doc value以修复此问题
更新2:得到另一个错误:
"function score query returned an invalid score: NaN for doc: 1739"
将公式更改为ceil((log10(_score+1)+5)*100)*10000+(9999-ceil(log10(doc['price'].value>0?doc['price'].value:1)*1000)
将+1替换为表达式
更新3:得到另一个错误:
不再有错误消息,现在很难找到,但它与前面的类似:(
将公式更改为ceil(_score+1)+ceil((doc['price'].value>0?doc['price'].value:1)*100)
简化公式,这样我就可以理解了,它现在仍然有效:)
问题内容: 我有ElasticSearch 5,我想根据字段值进行排序。想象一下,具有类别(例如流派)的文档可能具有科幻,戏剧,喜剧等值,并且在进行搜索时,我想对值进行排序,以便首先出现喜剧,然后是科幻和戏剧。然后,我当然会按照其他条件在小组内订购。有人可以指出我该怎么做吗? 问题答案: 使用手动排序进行Elasticsearch排序 在可以根据字段的特定值分配顺序的情况下,这是可能的。 我已经使
问题内容: 我的索引中有与- 相关的文档,并希望获取按孩子数排序的父母名单。有什么办法吗?我正在使用1.5.1 现在,通过使用功能,我可以轻松获得子文档的数量以及父查询的结果,但是似乎无法从脚本或搜索/评分功能访问值。有任何想法吗? 问题答案: 好吧,我终于找到了答案。感谢@doctorcal在#elasticsearch IRC 上的提示 正如我在这个问题提到的,我们可以使用每个家长让孩子的名单
问题内容: 这是场景: 想象一下,注册用户使用创建了一个新实体,而其他注册用户创建了一个新实体,依此类推… 我想要做的是根据记录价格对记录进行排序,具体取决于前端用户选择的货币(欧元或美元)。 我无法编制索引,例如或,因为费率每小时都会变化,但是如果可能的话,更新10000条记录价格的最佳方法是什么? 1-以下是我的建议,它可行,但是我认为这可能是更好的方法,有什么建议吗? 2-如果没有,哪种性能
问题内容: 我正在通过NEST c#使用ElasticSearch。我有很多关于人的信息 我希望能够按lastName以及长度的顺序对项目列表进行过滤和排序,因此名称中只有5个字符的人会出现在结果集的开头,然后是10个字符的人。 所以我想用一些伪代码做类似的事情 我是ElasticSearch的新手,所以任何示例都将非常有帮助。 问题答案: 您可以使用基于脚本的排序进行排序。 作为一个玩具示例,我
问题内容: 我的方法有问题。例如,我有带有Text()的索引字段: 当我尝试执行带有排序的搜索查询时,出现错误: elasticsearch.exceptions.RequestError:TransportError(400,’search_phase_execution_exception’,’默认情况下,文本字段上的字段数据是禁用的。在[title]上设置fielddata = true以便
我想按字段存在对我的ES搜索结果进行排序,假设我得到了字段“价格”,并希望所有有价格的结果都在顶部,所有没有价格的结果都在底部。我知道你可以做一个简单的排序并添加“缺失”:“_last”,例如: {“sort”:[{price':{missing':'u last',order':'asc'}}]} 但在这种情况下,结果也将按价格排序,我不想要它。 没有脚本有办法做到吗?