使用ElasticSearch(C#/ NEST)获取按时间戳排序的所有文档

时间:2016-06-30 12:35:24

标签: c# elasticsearch nest

我有一个elasticsearch数据库,我将type和timestamp字段定义为:

public Common.MediaType Type        { get; set; }
public DateTime Timestamp           { get; set; }

如何进行查询以返回X条目,匹配特定类型并按时间戳排序?

如果我这样做:

        var Match = Index.Driver.Search<Metadata>(_ => _
            .Query(Q => Q.Term(P => P.Type, Type))
            .Size(NumberOfItems)
            .Sort(Q => Q.Descending(P => P.Timestamp)));

它将失败,因为它将从正确的类型返回 NumberOfItems 记录,然后按时间戳对它们进行排序,因此它很可能会错过具有最新时间戳的记录。

我想要的是使时间戳成为查询的一部分,以便我得到 NumberOfItems 记录,这些记录按照匹配正确类型的 TimeStamp 排序。

但我不知道怎么写这个......

2 个答案:

答案 0 :(得分:2)

我理解正确,前5个Metadata文档类型在群集中的所有索引中都有最新的时间戳?

如果那是你想要的,那么以下内容将起作用

var Type = "metadata-type";
var NumberOfItems = 5;

var searchResponse = client.Search<Metadata>(s => s
    .AllIndices()
    .Query(q => q
        .Term(f => f.Type, Type)
    )
    .Size(NumberOfItems)
    .Sort(sort => sort
        .Descending(f => f.Timestamp)
    )
);

AllIndices()将在所有索引中搜索Metadata个文档类型。如果您只想在一个特定索引或多个特定索引中搜索,则可以用{/ 1>替换AllIndices()

.Index("index-1,index-2")

其中参数是您要搜索的索引名称的逗号分隔列表。

您需要考虑的一点是,索引到Elasticsearch的文档与可用于搜索结果的文档之间存在间隔。默认情况下,此间隔为1秒,这是可以设置为的最短时间。

修改

来自你的评论:

  

目前,如果所有记录都是正确的类型,而我想要5个项目,则需要前5个并对它们进行排序;但是记录6可能有更高的时间戳值,但它不会包含在匹配该类型的查询结果中。

Elasticsearch将如何采用前5项?它将根据某个值首先对项目进行排序,在这种情况下,它将按照查询中指定的时间戳降序排序,然后返回前5个文档。 它不会暗示文档的任意排序,取前5个,然后按时间戳降序排列这5个。

以下是演示

的示例
void Main()
{
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var defaultIndex = "default-index";
    var connectionSettings = new ConnectionSettings(pool)
            .DefaultIndex(defaultIndex);

    var client = new ElasticClient(connectionSettings);

    if (client.IndexExists(defaultIndex).Exists)
        client.DeleteIndex(defaultIndex);

    client.CreateIndex(defaultIndex, c => c
        .Mappings(m => m
            .Map<Metadata>(mm => mm.AutoMap())
        )
    );

    var metadata = Enumerable.Range(1, 1000).Select(i =>
        new Metadata
        {
            Id = i,
            Timestamp = DateTime.UtcNow.Date.AddDays(-(i-1)),
            Type = i % 2 == 0? "metadata-type-2" : "metadata-type-1"
        });

    client.IndexMany(metadata);
    client.Refresh(defaultIndex);

    var Type = "metadata-type-1";
    var NumberOfItems = 5;

    var searchResponse = client.Search<Metadata>(s => s
        .Query(q => q
            .Term(f => f.Type, Type)
        )
        .Size(NumberOfItems)
        .Sort(sort => sort
            .Descending(f => f.Timestamp)
        )
    );
}

public class Metadata
{
    public int Id { get; set;}

    public DateTime Timestamp { get; set;}

    [String(Index = FieldIndexOption.NotAnalyzed)]
    public string Type { get; set;}
}

对于搜索回复,我们会回来

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 500,
    "max_score" : null,
    "hits" : [ {
      "_index" : "default-index",
      "_type" : "metadata",
      "_id" : "1",
      "_score" : null,
      "_source" : {
        "id" : 1,
        "timestamp" : "2016-07-01T00:00:00Z",
        "type" : "metadata-type-1"
      },
      "sort" : [ 1467331200000 ]
    }, {
      "_index" : "default-index",
      "_type" : "metadata",
      "_id" : "3",
      "_score" : null,
      "_source" : {
        "id" : 3,
        "timestamp" : "2016-06-29T00:00:00Z",
        "type" : "metadata-type-1"
      },
      "sort" : [ 1467158400000 ]
    }, {
      "_index" : "default-index",
      "_type" : "metadata",
      "_id" : "5",
      "_score" : null,
      "_source" : {
        "id" : 5,
        "timestamp" : "2016-06-27T00:00:00Z",
        "type" : "metadata-type-1"
      },
      "sort" : [ 1466985600000 ]
    }, {
      "_index" : "default-index",
      "_type" : "metadata",
      "_id" : "7",
      "_score" : null,
      "_source" : {
        "id" : 7,
        "timestamp" : "2016-06-25T00:00:00Z",
        "type" : "metadata-type-1"
      },
      "sort" : [ 1466812800000 ]
    }, {
      "_index" : "default-index",
      "_type" : "metadata",
      "_id" : "9",
      "_score" : null,
      "_source" : {
        "id" : 9,
        "timestamp" : "2016-06-23T00:00:00Z",
        "type" : "metadata-type-1"
      },
      "sort" : [ 1466640000000 ]
    } ]
  }
}

我们按顺序返回包含13579的文档,因为这些是前5个文档与查询字词Timestamp匹配的最新"metadata-type-1"值。

答案 1 :(得分:0)

您可能想要使用Take而不是Size。

$( "#prodBasketPaymOptIdRow1 td:nth-child(2)" ).append( "Your text" );

首先排序,然后取第一个NumberOfItems文档。