2016-11-18 95 views
3

我索引我的查询,如下所示:使用NEST渗

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.Percolate电话,但它现在过时,他们建议使用搜索API,但是不要告诉如何使用过滤器使用它...

我使用ES V5和相同版本的NEST库。

回答

7

GA版本发布后,有计划将improve the documentation用于5.x;据我所知,许多地方的文件可能会更清晰,并且在此领域的任何帮助都将非常感谢:)

The documentation for the Percolate querythe integration test for it生成。在这里拉出所有的作品,using details from you other question。首先,让我们定义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使用LogEntryModelPercolatedQuery作为请求中的泛型类型参数(例如,在.Search<T>()中)发出请求时,它将使用推断的索引名称和类型名称(如果它们在请求中没有指定)。

现在,删除索引,这样我们可以从头开始

// delete the index if it already exists 
if (client.IndexExists(logIndex).Exists) 
    client.DeleteIndex(logIndex); 

启动并创建了PercolatedQueryQuery属性被映射为percolator型指数

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) 
       ) 
      ) 
     ) 
    ) 
); 

。这在Elasticsearch 5.0中是新的。该映射请求看起来像

{ 
    "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

{ 
    "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>() 
     ) 
    ) 
); 
+2

并非每个英雄都穿着斗篷。直到星期一,如果我没有工作解决方案,我的老板就会把我的脑袋弄掉。你真的救了我的命,所以谢谢你:)。 –

+0

不用担心,很高兴它有帮助:) –

+0

非常感谢你为这个漂亮的代码示例过滤器。 –