C # Nest и Elasticsearch Aggregations - PullRequest
       7

C # Nest и Elasticsearch Aggregations

0 голосов
/ 27 февраля 2019

Кто-нибудь знает, как сделать несколько агрегатов с гнездом?Я нашел немало примеров, к сожалению, ни один из них не работает.

Вот что у меня есть:

Vehicles fields = new Vehicles();

//create a terms query
var query = new TermsQuery
{
    IsVerbatim = true,
    Field = "VehicleOwnerId",
    Terms = new string[] { 25 },
};

var aggregations = new Dictionary<string, IAggregationContainer>
{
    { "years", new AggregationContainer
        {
            Terms = new TermsAggregation(nameof(fields.Year))
            {
                Field = new Field(nameof(fields.Year))
            }
        }
    }
    //,
    //{ "makes", new AggregationContainer
    //    {
    //        Terms = new TermsAggregation("Make")
    //        {
    //            Field = new Field(nameof(fields.Make))
    //        }
    //    }
    //}
};

//create the search request
var searchRequest = new SearchRequest
{
    Query = query,
    From = 0,
    Size = 100,
    Aggregations = aggregations
};

var result = client.SearchAsync<InventoryLiveView>(searchRequest).Result;

var years = result.Aggregations.Terms("years");
Dictionary<string, long> yearCounts = new Dictionary<string, long>();
foreach (var item in years.Buckets)
{
    yearCounts.Add(item.Key, item.DocCount ?? 0);
}

Если я просто выполню код, подобный этому, он будет работать.Годы возвращает совокупности, как и ожидалось.Если я попытаюсь добавить другое поле (как закомментировано выше), оно завершится неудачно, и я получу ноль записей.Как я могу получить несколько агрегатов в одном запросе?Я вижу примеры всего этого, но ни один из примеров, которые я пробовал, кажется, не работает, и большинство из них устарели (включая некоторые в документации Nest).Я также попробовал этот подход, который довольно близок к документации.

//create the search request
var searchRequest = new SearchRequest
{
    Query = query,
    From = 0,
    Size = 100,
    //Aggregations = aggregations
    Aggregations = new AggregationDictionary
    {
        { 
            "childAgg", new ChildrenAggregation("childAgg", typeof(Vehicles ))
            {
                Aggregations = new AggregationDictionary
                {
                    {"years", new TermsAggregation(nameof(fields.VehicleYear))},
                    {"makes", new TermsAggregation(nameof(fields.VehicleMakeName))},
                    {"models", new TermsAggregation(nameof(fields.VehicleModelName))},
                }
            }
        }
    }
};

var result = client.SearchAsync<Vehicles>(searchRequest).Result;

Это просто создает исключение нулевой ссылки.

1 Ответ

0 голосов
/ 27 февраля 2019

Я думаю, я никогда не буду слишком беспокоиться о том, чтобы стать гордым программистом :) Слишком часто решение этой проблемы заставляет меня чувствовать себя глупо, когда оно проявляет себя.

Так что моя проблема заключалась в том, чтополе, которое я пытался использовать в агрегации, было текстовым и не могло быть использовано.Я переключил все на поля идентификаторов, и несколько агрегатов работают, как и ожидалось.

Так что эта версия кода работает как чемпион:

Vehicle fields = new Vehicle ();

//create a terms query
var query = new TermsQuery
{
    IsVerbatim = true,
    Field = "VehicleOwnerId",
    Terms = new string[] { "30" },
};

string[] Fields = new[]
{
    nameof(fields.Year),
    nameof(fields.MakeId),
    nameof(fields.ModelId)
};

var aggregations = new Dictionary<string, IAggregationContainer>();
foreach (string sField in Fields)
{
    var termsAggregation = new TermsAggregation(sField)
    {
        Field = sField
    };

    aggregations.Add(sField, new AggregationContainer { Terms = termsAggregation });
}

//create the search request
var searchRequest = new SearchRequest
{
    Query = query,
    From = 0,
    Size = 10,
    Aggregations = aggregations
};

var result = client.SearchAsync<InventoryLiveView>(searchRequest).Result;

var years = result.Aggregations.Terms(nameof(fields.Year));
Dictionary<string, long> yearCounts = new Dictionary<string, long>();
foreach (var item in years.Buckets)
{
    yearCounts.Add(item.Key, item.DocCount ?? 0);
}

Точная ошибка от упругого поиска, которую я видел, используяпочтальон был:

Fielddata is disabled on text fields by default. Set fielddata=true on [MakeName] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.

...