我目前正在忙于一个项目,我们选择使用Elasticsearch作为分类广告网站的搜索引擎。
目前,我有以下业务规则:
每页列出25个广告。在这25个中,显示的10个广告必须是“付费广告”,其他15个必须是“免费”。所有25个必须与所执行的搜索相关(即关键字,地区,价格,类别等)
我知道我可以使用两个单独的查询来做到这一点,但这似乎是一种巨大的资源浪费。是否可以进行“子查询”(如果你可以调用它们?)并将这些结果合并到一个结果集中?不知怎的,只在一个查询中从elasticsearch获取10个“付费”广告和15个“免费”广告?当然假设有足够的广告使这个要求成为可能。
感谢您的帮助!
编辑 - 只需添加我的地图信息,以便更加清晰。
"properties": {
"advertText": {
"type": "string",
"boost": 2,
"store": true,
"analyzer": "snowball"
},
"canonical": {
"type": "string",
"store": true
},
"category": {
"properties": {
"id": {
"type": "string",
"store": true
},
"name": {
"type": "string",
"store": true
},
"parentCategory": {
"type": "string",
"store": true
}
}
},
"contactNumber": {
"type": "string",
"index": "not_analyzed",
"store": true
},
"emailAddress": {
"type": "string",
"store": true,
"analyzer": "url_email_analyzer"
},
"advertType": {
"type": "string",
"index": "not_analyzed"
},
...
}
我想要的是能够查询这个并获得10个结果,其中“advertType”:“付费”和 15其中“advertType”:“免费”......
答案 0 :(得分:6)
您可以采取几种方法。
首先,您可以尝试使用多搜索API:
多重搜索API
多搜索API允许在其中执行多个搜索请求 相同的API。它的端点是_msearch。
请求的格式类似于批量API格式
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-multi-search.html
一个基本的例子:
curl -XGET 'http://127.0.0.1:9200/advertising_index/_msearch?pretty=1' -d '
{}
{"query" : {"match" : {"Paid_Ads" : "search terms"}}, "size" : 10}
{}
{"query" : {"match" : {"Free" : "search terms"}}, "size" : 15}
'
我已经编写了字段和查询但总的来说你应该得到这个想法 - 你点击_msearch端点并从空括号{}
开始传递一系列查询。对于付费我已将大小设置为10并且对于免费我将大小设置为15.
根据您自己实施的细节,您应该可以使用类似的东西。
如果由于某种原因无效,您也可以尝试使用限制过滤器:
限制过滤器
限制过滤器限制要执行的文档数(每个分片) 上。例如:
{ "filtered" : { "filter" : { "limit" : {"value" : 100} }, "query" : { "term" : { "name.first" : "shay" } } } }
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-limit-filter.html
请注意,限制是每个分片,而不是每个索引。给定每个索引默认5个主分片,要获得总响应10,您可以将限制设置为2(2X5 == 10)。另请注意,如果您在一个分片上有多个匹配但在另一个分片上没有匹配,则会产生不完整的结果。
然后,您可以将两个过滤器与bool过滤器结合使用:
布尔过滤器
匹配匹配其他布尔组合的文档的过滤器 查询。概念类似于布尔查询,但子句除外 是其他过滤器。可以放在接受过滤器的查询中。
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html
我没有详细说明这一点,因为它需要有关您的特定索引,映射,数据和查询的更多信息。
答案 1 :(得分:0)
尝试使用限制过滤器来限制返回的文档数量
{
"filtered" : {
"filter" : {
"limit" : {"value" : 10}
},
"query" : {
"term" : { "name.first" : "shay" }
}
}
}
将值更改为2以获得10个结果,将3更改为15
答案 2 :(得分:-4)
您要求查询?
(select * from tablename where advert = "Paid Advert" limit 10) union (select * from tablename where advert = "Free" limit 15);
每页生成限制的逻辑?