Как использовать прокрутку при передаче необработанного json-запроса в ElasticSearch с помощью NEST

var query = @"
        {
          ""query"": {
            ""match_all"": { }                    
          }
        }";

    Func<SearchRequestParameters, SearchRequestParameters> requestParameters = a => 
                                                a.SearchType(SearchType.Scan).Scroll(TimeSpan.FromSeconds(60));

        var searchResult = await client.LowLevel.SearchAsync<SearchResponse<T>>(indexName, mappingName, query , requestParameters)

if (searchResult.Body.IsValid)
            {
                var scrollNo = 0;                
                var results = await client.ScrollAsync<T>("10s", searchResult.Body.ScrollId);

                while (results.Documents.Any())
                {
                    documents.AddRange(results.Documents);
                    scrollNo++;

                    results = await client.ScrollAsync<T>("10s", results.ScrollId);

                return new Customresponse<T>
                {
                    Documents = documents,
                    total = result.Body.Total
                };
            }

Хотел бы получить все данные с помощью прокрутки при передаче необработанного запроса json. но прокрутка не работает должным образом при передаче необработанного запроса json. Может ли кто-нибудь помочь в этом?


person Sasi    schedule 05.01.2017    source источник
comment
В приведенном выше запросе отсутствует прокрутка. что ты уже испробовал?   -  person Russ Cam    schedule 15.01.2017
comment
Я пробовал, как показано ниже. Func‹SearchRequestParameters, SearchRequestParameters› requestParameters = a =› a.SearchType(SearchType.Scan).Scroll(TimeSpan.FromSeconds(60));   -  person Sasi    schedule 16.01.2017
comment
Я пытался передать этот запрос и цикл while с API прокрутки, но не работал должным образом. Func‹SearchRequestParameters, SearchRequestParameters› requestParameters = a =› a.SearchType(SearchType.Scan).Scroll(TimeSpan.FromSeconds(60));   -  person Sasi    schedule 16.01.2017
comment
Пожалуйста, не могли бы вы отредактировать свой вопрос, чтобы добавить какие-либо дополнительные детали?   -  person Russ Cam    schedule 17.01.2017
comment
@RussCam, я обновил свой вопрос, добавив более подробную информацию, можете ли вы предложить мне, если у вас есть какие-либо предложения?   -  person Sasi    schedule 31.01.2017
comment
что такое T в вашем примере?   -  person Russ Cam    schedule 01.02.2017


Ответы (1)


Ваш пример почти готов, но не совсем; вам не хватает закрывающей скобки для цикла while для сбора всех документов перед возвратом пользовательского ответа.

Вот пример, который я только что запустил в наборе данных Stackoverflow, чтобы вернуть все вопросы с тегом nest.

private IElasticClient _client;

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

    _client = new ElasticClient(connectionSettings);

    var query = @"
    {
    ""query"": {
      ""term"": {
        ""tags"": {
          ""value"": ""nest""
          }
        }
      }
    }";

    var result = RunScrollAsync(query).Result.Dump();
}

private async Task<Customresponse<Question>> RunScrollAsync(string query)
{
    var scrollTime = "10s";

    // omit the .SearchType(Scan) which is deprecated. Not 
    // specifying means the first response contains the first set
    // of documents
    var esResponse = await _client.LowLevel.SearchAsync<SearchResponse<Question>>(
        "posts", 
        "question", 
        query, r => r.Scroll(TimeSpan.FromSeconds(10))).ConfigureAwait(false);

    if (esResponse.Body.IsValid && esResponse.Body.Documents.Any())
    {
        // assume you have less than 2,147,483,647 documents to return?
        var documents = new List<Question>((int)esResponse.Body.Total);
        documents.AddRange(esResponse.Body.Documents);

        var scrollNo = 0;

        var response = await _client.ScrollAsync<Question>(scrollTime, esResponse.Body.ScrollId).ConfigureAwait(false);;

        // keep scrolling until no more documents are returned
        while (response.Documents.Any())
        {
            documents.AddRange(response.Documents);
            scrollNo++;

            response = await _client.ScrollAsync<Question>(scrollTime, response.ScrollId).ConfigureAwait(false);;
        }

        return new Customresponse<Question>
        {
            Documents = documents,
            total = response.Total
        };
    }

    // return an empty result. 
    // Or throw an exception, or log - whatever you need to do
    return new Customresponse<Question>
    {
        Documents = Enumerable.Empty<Question>(),
        total = 0
    };
}

public class Customresponse<T>
{
    public IEnumerable<T> Documents { get; set; }

    public long total { get; set; }
}

Это возвращает все 342 вопроса, всего 342 (набор данных за июнь 2016 г.).

person Russ Cam    schedule 31.01.2017
comment
можем ли мы получить пакет за пакетом, используя прокрутку, например, если у меня есть 100 тыс. данных, я хочу получать 25 тыс. на каждый запрос, используя прокрутку по требованию. например, после того, как мы получим 25 КБ, и когда пользователь снова щелкнет, чтобы получить следующие 25 КБ данных и т. д.?. - person Sasi; 02.02.2017
comment
лучше всего начать с документации Scroll API: elastic.co/guide/en/elasticsearch/reference/current/ Прокрутка держит курсор (термин используется здесь вольно) открытым в кластере, после чего он закрывается. Для разбиения на страницы используются from и size, а для глубокого разбиения на страницы смотрите search_after - person Russ Cam; 02.02.2017
comment
Привет, Расс, при прокрутке я получаю «Исключение отсутствия контекста поиска», он работал нормально, но теперь получаю, когда я выполнил приведенный выше код. есть идеи ??.. # Ответ: {ошибка:{root_cause:[{type:search_context_missing_exception,reason:Не найден контекст поиска для id [56162426]} - person Sasi; 24.09.2017