我索引我的查询,如下所示:
client.Index(new PercolatedQuery { Id = "std_query", Query = new QueryContainer(new MatchQuery { Field = Infer.Field<LogEntryModel>(entry => entry.Message), Query = "just a text" }) }, d => d.Index(EsIndex)); client.Refresh(EsIndex);
现在,如何使用ES的过滤器功能将传入文档与此查询匹配?要说在这方面缺少NEST文档,那就太轻描淡写了。我尝试使用client.Percolatecall,但是现在不推荐使用,他们建议使用search api,但不要告诉如何将其与percolator一起使用…
client.Percolate
我正在使用 ES v5 和相同版本的NEST lib。
GA发布后,有计划改进 5.x 的文档。我知道在许多地方文档可能会更清晰,对此领域的任何帮助将不胜感激:)
Percolate查询的文档是从集成测试中生成的。在此使用来自其他问题的详细信息,拉出所有示例的示例。首先,让我们定义POCO模型
public class LogEntryModel { public string Message { get; set; } public DateTimeOffset Timestamp { get; set; } } public class PercolatedQuery { public string Id { get; set; } public QueryContainer Query { get; set; } }
我们将流畅地映射所有属性,而不是使用映射属性。流畅的映射功能最强大,可以表达所有在Elasticsearch中进行映射的方式。
现在,创建连接设置和客户端以使用Elasticsearch。
var pool = new SingleNodeConnectionPool(new Uri($"http://localhost:9200")); var logIndex = "log_entries"; var connectionSettings = new ConnectionSettings(pool) // infer mapping for logs .InferMappingFor<LogEntryModel>(m => m .IndexName(logIndex) .TypeName("log_entry") ) // infer mapping for percolated queries .InferMappingFor<PercolatedQuery>(m => m .IndexName(logIndex) .TypeName("percolated_query") ); var client = new ElasticClient(connectionSettings);
我们可以指定索引名称和类型名称来推断我们的POCO。也就是说,当NEST使用LogEntryModel或PercolatedQuery作为请求中的泛型类型参数(例如Tin.Search<T>())发出请求时,如果未在请求中指定它们,则将使用推断的索引名和类型名。
LogEntryModel
PercolatedQuery
T
.Search<T>()
现在,删除索引,以便我们从头开始
// delete the index if it already exists if (client.IndexExists(logIndex).Exists) client.DeleteIndex(logIndex);
并创建索引
client.CreateIndex(logIndex, c => c .Settings(s => s .NumberOfShards(1) .NumberOfReplicas(0) ) .Mappings(m => m .Map<LogEntryModel>(mm => mm .AutoMap() ) .Map<PercolatedQuery>(mm => mm .AutoMap() .Properties(p => p // map the query field as a percolator type .Percolator(pp => pp .Name(n => n.Query) ) ) ) ) );
上的Query属性PercolatedQuery被映射为percolator类型。这是Elasticsearch5.0中的新功能。映射请求看起来像
Query
percolator
{ "settings": { "index.number_of_replicas": 0, "index.number_of_shards": 1 }, "mappings": { "log_entry": { "properties": { "message": { "fields": { "keyword": { "type": "keyword" } }, "type": "text" }, "timestamp": { "type": "date" } } }, "percolated_query": { "properties": { "id": { "fields": { "keyword": { "type": "keyword" } }, "type": "text" }, "query": { "type": "percolator" } } } } }
现在,我们准备为查询建立索引
client.Index(new PercolatedQuery { Id = "std_query", Query = new MatchQuery { Field = Infer.Field<LogEntryModel>(entry => entry.Message), Query = "just a text" } }, d => d.Index(logIndex).Refresh(Refresh.WaitFor));
索引查询后,让我们对文档进行渗透
var logEntry = new LogEntryModel { Timestamp = DateTimeOffset.UtcNow, Message = "some log message text" }; // run percolator on the logEntry instance var searchResponse = client.Search<PercolatedQuery>(s => s .Query(q => q .Percolate(p => p // field that contains the query .Field(f => f.Query) // details about the document to run the stored query against. // NOTE: This does not index the document, only runs percolation .DocumentType<LogEntryModel>() .Document(logEntry) ) ) ); // outputs 1 Console.WriteLine(searchResponse.Documents.Count());
带有ID的渗透查询"std_query"返回到searchResponse.Documents
"std_query"
searchResponse.Documents
{ "took" : 117, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 0.2876821, "hits" : [ { "_index" : "log_entries", "_type" : "percolated_query", "_id" : "std_query", "_score" : 0.2876821, "_source" : { "id" : "std_query", "query" : { "match" : { "message" : { "query" : "just a text" } } } } } ] } }
这是渗透文档实例的示例。渗滤还可以对已经建立索引的文档运行
var searchResponse = client.Search<PercolatedQuery>(s => s .Query(q => q .Percolate(p => p // field that contains the query .Field(f => f.Query) // percolate an already indexed log entry .DocumentType<LogEntryModel>() .Id("log entry id") .Index<LogEntryModel>() .Type<LogEntryModel>() ) ) );