有一个“人”类型的文件,有两个字段“城市”和“性别”,例如
person : {
"name" : "x",
"city" : "stockholm",
"gender" : "m"
}
示例数据:
person: {name: "x", "city" : "stockholm", "gender" : "m"}
person: {name: "y", "city" : "stockholm", "gender" : "m"}
person: {name: "z", "city" : "stockholm", "gender" : "m"}
person: {name: "zz", "city" : "stockholm", "gender" : "f"}
person: {name: "xy", "city" : "uppsala", "gender" : "m"}
person: {name: "xz", "city" : "stockholm", "gender" : "m"}
person: {name: "yy", "city" : "uppsala", "gender" : "f"}
首次质询:选择2名随机的人居住在斯德哥尔摩
size: 2,
"query": {
"function_score": {
"query": {
"term": {
"city": {
"value": "stockholm"
}
}
},
"functions": [
{
"random_score": {
"seed": 314159265359
}
}
]
}
}
以上查询的总点击数为5,其中随机选择了2个结果
possible result (As it can be random):
person: {name: "y", "city" : "stockholm", "gender" : "m"}
person: {name: "zz", "city" : "stockholm", "gender" : "f"}
第二个查询:现在我想选择性别为“m”但第一次查询选择不的人。
之类的东西bool : must [{
term: {
"gender" : "m"
}
}]
must_not : [{ /*NOT SELECTED BY FIRST QUERY i.e name = y, zz */}]
result:
person: {name: "x", "city" : "stockholm", "gender" : "m"}
person: {name: "z", "city" : "stockholm", "gender" : "m"}
person: {name: "xy", "city" : "uppsala", "gender" : "m"}
person: {name: "xz", "city" : "stockholm", "gender" : "m"}
这可以通过弹性搜索中的任何方式实现吗?可能通过过滤器(使用BitSet快速访问文档ID)或dismax查询?
请注意,数据大小以百万为单位,如果我从第一个查询中提取导致数千万的数据,则需要花费大量时间,这在我们的方案中是不可接受的。我只需要计数而不是两个查询中的实际数据。
我不介意在一个查询中尽可能地做,但我不知道该怎么做。
答案 0 :(得分:0)
我用你的数据做了一个简单的测试用例。
如果查询返回随机数据,则必须进行两次查询 第一个返回n行,你必须取结果的n ids /属性,并从第二个中排除它们
第二个查询可能是(我编写了一个过滤器来排除名为'x'和'zz'的人):
{
"aggs":{
"persons":{
"filter":{
"bool":{
"must_not":{
"term":{
"name":"x"
}
},
"must_not":{
"term":{
"name":"zz"
}
}
}
},
"aggs":{
"gender":{
"terms":{
"field":"gender"
}
}
}
}
}
}
按性别分组的结果是
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 7,
"max_score": 0,
"hits": [
]
},
"aggregations": {
"persons": {
"doc_count": 5,
"gender": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "m",
"doc_count": 4
},
{
"key": "f",
"doc_count": 1
}
]
}
}
}
}
第二个查询按性别返回计数,不包括上一个查询的两个结果。
对于firt查询,我认为你需要一个不同的随机实现。如果您有数百万行,并且您首先为每个行分配一个随机数,然后按行数对行进行排序,则不可避免地需要花费大量时间。更明智的解决方案是为每个文档使用序列字段,存储它,然后在[序列值的0..max]范围内生成两个随机数。使用这两个数字,您可以非常快速地查询数据并应用第二个查询。使用此解决方案,响应时间会快得多。