我需要将搜索结果分为两部分。 1,其中> 0的商品按价格排序,然后先提取。 2个数量= 0的产品按价格排序,并在库存的那些产品之后显示。最主要的是,在第一类商品(数量> 0)中没有第二类商品(数量= 0),不幸的是,当我根据两个条件进行排序时
使用PHP 7.1 和Elastic Search 6.6.0
小例子,有一张桌子
id | site_price | count
1 | 10 | 0
2 | 5 | 5
3 | 15 | 2
4 | 20 | 10
5 | 15 | 0
我需要先按数量排序,然后再按价格排序(不丢失第一个排序)。
第一类:('count'=>'desc')
。
第二种:('site_price'=>'asc')
。
应该得到以下结果:
id | site_price | count
2 | 5 | 10
3 | 15 | 5
4 | 20 | 2
1 | 10 | 0
5 | 15 | 0
$this->params['body'] = array(
'from' => ($filters['page'] - 1) * 15,
'size' => 15,
'query' => array(
'bool' => array(
'must' => array(
"query_string" => array(
'query' => "*" . $filters['text'] . "*",
)
),
)
),
'sort' => array(
array("shops_count" => "desc"),
array("site_price" => "asc")
)
);
$result = $this->client->search($this->params);
答案 0 :(得分:0)
@Nikolay,感谢您的帮助。 不幸的是,这没有帮助。我尝试重写查询-但结果是相同的。这是一个例子:删除过多,只剩下搜索和排序
enter code here
$this->params['body'] = array(
'from' => ($filters['page'] - 1) * 15,
'size' => 15,
'query' => array(
'bool' => array(
'must' => array(
"query_string" => array(
'query' => "*" . $filters['text'] . "*",
)
),
)
),
'sort' => array(
array("shops_count" => "desc"),
array("site_price" => "asc")
)
);
$result = $this->client->search($this->params);
答案 1 :(得分:0)
您似乎想要实现与SQL中的UNION类似的行为,因为您首先要将结果集分成2组,对每个组进行排序,然后将一个组接一个接一个。
有几种方法可以实现。
与this answer类似,建议执行2个查询:
POST /orders/_search
{
"query": {
"range": {
"count": {
"gt": 0
}
}
},
"sort" : [
{"site_price": "asc"},
]
}
POST /orders/_search
{
"query": {
"range": {
"count": {
"gte": 0,
"lte": 0
}
}
},
"sort" : [
{"site_price": "asc"},
]
}
然后在客户端加入他们。 还有一种方法可以在Elasticsearch方面完全做到这一点。
我们可以使用script based sorting并首先对可用性(count > 0
)进行排序,然后按价格排序:
POST /orders/_search
{
"sort" : [
{
"_script" : {
"type" : "number",
"script" : {
"lang": "painless",
"source": "if (doc['count'].value > 0) { 1 } else { 0 } "
},
"order" : "desc"
}
},
{"site_price": "asc"}
]
}
但是,脚本编写始终会带来性能开销。解决方案#1虽然执行2个查询,但更为可靠。
这是另一种使用单个查询并且不使用昂贵的脚本的解决方案。
如果我们添加特殊字段"available"
,则无需使用脚本排序。
文档可能如下所示:
doc1 = {
"id": 1,
"site_price": 10,
"count": 0,
"available": 0
}
doc2 = {
"id": 2,
"site_price": 5,
"count": 5,
"available": 1
}
然后排序将如下所示:
POST /orders/_search
{
"sort" : [
{"available": "desc"},
{"site_price": "asc"}
]
}
这是一个称为denormalization的通用模式,在调整最佳性能时证明是有用的。
希望有帮助!