我正在使用ES 5.在C#上使用Nest lib。
我的模型中有两个实体,联系人和事件。我有一个要求,我必须得到所有联系,而不是超过N个事件(非常类似于对SQL的查询)。联系人是事件父母,因此我可以使用父/子策略进行过滤。
我能够获得联系人的聚合,因为我无法通过这些聚合来过滤联系人。
我做了类似的事情:
var queryResult = client.Search<Contact>(s => s
.Index("contact*")
.Query(q => q
...
)
.Aggregations(a => a
.Children<Event>("filter_event", ca => ca.Aggregations(ca2 => ca2
.Filter("filter1", f => f.Filter(fq => fq.Term(t => t.Field(tf => tf.EventName).Value("Event1")))
.Aggregations(fa => fa
.Terms("filter1Contacts", v => v.Field(faf => faf.EventContactGuid).Size(int.MaxValue).MinimumDocumentCount(5))
)
)
)))
);
使用此代码,我只能获得超过5个事件的联系人的聚合,但我没有找到根据这些聚合结果过滤联系人的方法。
在ES 5中有一种方法可以做到这一点吗?
答案 0 :(得分:1)
您可以使用has_child
query,这是尝试Linqpad
void Main()
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var defaultIndex = "orders";
var connectionSettings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex)
.InferMappingFor<Order>(m => m
.IdProperty(f => f.Customer)
)
.PrettyJson()
.DisableDirectStreaming()
.OnRequestCompleted(response =>
{
// log out the request
if (response.RequestBodyInBytes != null)
{
Console.WriteLine(
$"{response.HttpMethod} {response.Uri} \n" +
$"{Encoding.UTF8.GetString(response.RequestBodyInBytes)}");
}
else
{
Console.WriteLine($"{response.HttpMethod} {response.Uri}");
}
Console.WriteLine();
// log out the response
if (response.ResponseBodyInBytes != null)
{
Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
$"{Encoding.UTF8.GetString(response.ResponseBodyInBytes)}\n" +
$"{new string('-', 30)}\n");
}
else
{
Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
$"{new string('-', 30)}\n");
}
});
var client = new ElasticClient(connectionSettings);
if (client.IndexExists(defaultIndex).Exists)
client.DeleteIndex(defaultIndex);
client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map<Order>(mm => mm.AutoMap())
.Map<OrderLine>(mm => mm
.Parent<Order>()
.AutoMap()
)
)
);
var orders = new[]
{
new Order { Customer = "Bilbo Baggins" },
new Order { Customer = "Gandalf the Grey" }
};
var orderlines = new Dictionary<string, OrderLine[]>
{
{ "Bilbo Baggins",
new []
{
new OrderLine { ItemNumber = 1 },
new OrderLine { ItemNumber = 2 },
new OrderLine { ItemNumber = 3 },
new OrderLine { ItemNumber = 4 },
new OrderLine { ItemNumber = 5 }
}
},
{ "Gandalf the Grey",
new []
{
new OrderLine { ItemNumber = 1 },
new OrderLine { ItemNumber = 2 },
new OrderLine { ItemNumber = 3 },
new OrderLine { ItemNumber = 4 }
}
}
};
client.IndexMany(orders);
foreach (var lines in orderlines)
{
client.Bulk(b => b
.IndexMany(lines.Value, (bi, d) => bi.Parent(lines.Key))
);
}
client.Refresh(defaultIndex);
var queryResult = client.Search<Order>(s => s
.Query(q => +q
.HasChild<OrderLine>(c => c
.Query(cq => +cq.MatchAll())
// min number of child documents that must match
.MinChildren(5)
)
)
);
}
public class Order
{
public string Customer { get; set; }
}
public class OrderLine
{
public int ItemNumber { get; set; }
}
查询结果仅返回Bilbo Baggins
Status: 200
{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.0,
"hits" : [ {
"_index" : "orders",
"_type" : "order",
"_id" : "Bilbo Baggins",
"_score" : 0.0,
"_source" : {
"customer" : "Bilbo Baggins"
}
} ]
}
}