SilverMoon17
SilverMoon17

Reputation: 51

How to create a valid query to search for an object with nested objects in Elastic Search using Elastic.Clients.Elasticsearch

I just started learning ElasticSearch and my problem is that searching with Elastic Search is not working. And I can't find normal documentation for Elastic.Clients.Elasticsearch to understand why it doesn't work

This is what my model for the database looks like:

public class Product : BaseModel
{
    public string SKU { get; set; }
    public Category Category { get; set; }
    public int CategoryId { get; set; }
    public List<string> ImageUrls { get; set; }
    public decimal MinimalPrice { get; set; }
    public string Store1ArticleNumber { get; set; }
    public string Store2ArticleNumber { get; set; }
    public string Store3ArticleNumber { get; set; }
    public string Store4ArticleNumber { get; set; }

    public ICollection<ProductLocalization> Localizations { get; set; }
}
public class Category : BaseModel
{
    public string NameRu { get; set; } = string.Empty;
    public string NameEn { get; set; } = string.Empty;
    public string NameRo { get; set; } = string.Empty;
    public string DescriptionRu { get; set; } = string.Empty;
    public string DescriptionEn { get; set; } = string.Empty;
    public string DescriptionRo { get; set; } = string.Empty;
}
public class ProductLocalization : BaseModel
{
    public int ProductId { get; set; }
    public Language LanguageCode { get; set; } 
    public string TranslatedName { get; set; }
    public string TranslatedDescription { get; set; }
    public string TranslatedShortDescription { get; set; }

    [JsonIgnore]
    public Product Product { get; set; }
}

This is how I set up my index for this data

var createIndexResponse = await _elasticClient.Indices.CreateAsync<Product>("products", p => p
        .Mappings(map => map
            .Properties(prop => prop
                .Keyword(p => p.SKU)
                .Keyword(p => p.CactusArticleNumber)
                .Keyword(p => p.DarwinArticleNumber)
                .Keyword(p => p.EnterArticleNumber)
                .Keyword(p => p.UltraArticleNumber)
                .Object(p => p.Category, obj => obj
                    .Properties(ps => ps
                        .Text(t => t.Category.NameRu)
                        .Text(t => t.Category.NameEn)
                        .Text(t => t.Category.NameRo)
                        .Text(t => t.Category.DescriptionRu)
                        .Text(t => t.Category.DescriptionEn)
                        .Text(t => t.Category.DescriptionRo)
                    )
                )
                .Nested(p => p.Localizations, n => n
                    .Properties(p => p
                    .Text(l => l.Localizations.First().TranslatedName)
                    .Text(l => l.Localizations.First().TranslatedDescription)
                    .Text(l => l.Localizations.First().TranslatedShortDescription)
                )
            )
        )
    )
);

And this is what my search function looks like:

public async Task<IEnumerable<Product>> SearchAsync(
    string searchTerm,
    int from = 0,
    int size = 10
)
{
    var response = await _elasticClient.SearchAsync<Product>(s => s
        .Index("products")
        .From(from)
        .Size(size)
        .Query(q => q
            .QueryString(qs => qs
                .Query(searchTerm)
            )
        )
    );

    if (!response.IsValidResponse)
    {
        // Handle error scenario, e.g. log or throw an exception.
        throw new Exception($"Search request failed: {response.ElasticsearchServerError?.Error.Reason}");
    }

    return response.Documents.ToList();
}

But it doesn't work, I understand why, but I can't find the right information on how to fix it using this package. Can you please tell me if I am creating the index correctly, what my search function should look like and where can I find normal documentation for this package, because on the official site it is very scarce?

I want it to search in that order:

SKU -> by articles of all stores -> by name in all languages -> by category name -> by description, by short description - > by category description

Upvotes: 0

Views: 24

Answers (0)

Related Questions