Realizando consultas com múltiplos campos facilmente usando RavenDB

Este exemplo é inspirado no livro do Ayende

Se você deseja aprender RavenDB, recomendo que se inscreva no RavenDB bootcamp (é grátis). Se já conhece RavenDB, então o livro do Ayende é um excelente recurso.

Considere este documento:

{
    "Company": "companies/62",
    "Employee": "employees/7",
    "OrderedAt": "1997-01-07T00:00:00.0000000",
    "RequireAt": "1997-02-18T00:00:00.0000000",
    "ShippedAt": "1997-01-13T00:00:00.0000000",
    "ShipTo": {
        "Line1": "Alameda dos Canàrios, 891",
        "Line2": null,
        "City": "Sao Paulo",
        "Region": "SP",
        "PostalCode": "05487-020",
        "Country": "Brazil"
    },
    "ShipVia": "shippers/1",
    "Freight": 108.04,
    "Lines": [
        {
            "Product": "products/1",
            "ProductName": "Chai",
            "PricePerUnit": 14.4,
            "Quantity": 10,
            "Discount": 0
        },
        {
            "Product": "products/21",
            "ProductName": "Sir Rodney's Scones",
            "PricePerUnit": 8,
            "Quantity": 30,
            "Discount": 0.1
        },
        {
            "Product": "products/28",
            "ProductName": "Rössle Sauerkraut",
            "PricePerUnit": 36.4,
            "Quantity": 42,
            "Discount": 0.1
        },
        {
            "Product": "products/36",
            "ProductName": "Inlagd Sill",
            "PricePerUnit": 15.2,
            "Quantity": 5,
            "Discount": 0.1
        },
        {
            "Product": "products/40",
            "ProductName": "Boston Crab Meat",
            "PricePerUnit": 14.7,
            "Quantity": 2,
            "Discount": 0.1
        }
    ]
}

O que fazer se desejarmos obter todos os pedidos contendo um produto em particular? Como seria a consulta?

var q =
    from order in session.Query<Order>()
    where order.Lines.Any(x => x.Product == "products/1")
    select order;

Simples, não é?! Mas, como você save, todos as consultas ao RavenDB usam um índice. Se não há um índice para a consulta, RavenDB cria um automaticamente.

Aqui está o mapeamento do índice criado pelo RavenDB para essa consulta.

from doc in docs.Orders
select new {
	Lines_Product = (
		from docLinesItem in ((IEnumerable<dynamic>)doc.Lines).DefaultIfEmpty()
		select docLinesItem.Product).ToArray()
}

A coisa interessante aqui é o uso de um array de strings. Quando RavenDB encontra uma coleção em um campo de índice, a indexação ocorre múltiplas vezes. Outro conceito importante é que o RavenDB irá “achatar” todas as coleções.

Então, vamos definir um índice nós mesmos.

public class Orders_SearchByProduct :
    AbstractIndexCreationTask<Order, Orders_SearchByProduct.QueryModel>
{
    public class QueryModel
    {
        public string Query;
    }

    public Orders_SearchByProduct()
    {
        Map = orders =>
            from order in orders
            select new
            {
                Query = new object[]
                {
                    order.Lines.Select(p => p.Product).ToArray(),
                    order.Lines.Select(p => p.ProductName).ToArray()
                }
            };
    }
}

Agora, podemos procurar pedidos que contenham um produto em específico considerando tanto o Id quanto o nome. Eis um exemplo:

using (var session = DocumentStoreHolder.Store.OpenSession())
{
    var q =
        session.Query<Orders_SearchByProduct.QueryModel,Orders_SearchByProduct>()
            .Where(o => o.Query == "Manjimup Dried Apples")
            .OfType<Order>();
                    
    foreach (var order in q.ToList())
    {
        Console.WriteLine(order.Id);
    }
}

O operador OfType é usado para mudar o tipo do resultado.

Era isso.

Compartilhe este insight:

Elemar Júnior

Sou fundador e CEO da EximiaCo e atuo como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

Elemar Júnior

Sou fundador e CEO da EximiaCo e atuo como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

Mais insights para o seu negócio

Veja mais alguns estudos e reflexões que podem gerar alguns insights para o seu negócio:

No meu tempo absolutamente livre – quando não estou trabalhando, estudando ou aproveitando com a família – tenho jogado Mario...
Mais preocupante que o posicionamento do presidente é sua falta de constância. Há dois dias, uma medida provisória proposta pelo...
The example which motivated this post comes from the excellent book Designing Distributed Systems by Brendan Burns (co-founder of the...
Dando continuidade a uma jornada iniciada há mais de 20 anos, comunico a fundação da Eximia! Trata-se de uma empresa...
Most of my client’s applications code is for parsing, caching, storing, aggregating, protecting and sharing data! It is not the...
What should be the execution result of the following code? using System; using System.Threading.Tasks; using static System.Console; using static System.IO.File;...
Masterclass

O Poder do Metamodelo para Profissionais Técnicos Avançarem

Nesta masterclass aberta ao público, vamos explorar como o Metamodelo para a Criação, desenvolvido por Elemar Júnior, pode ser uma ferramenta poderosa para alavancar sua carreira técnica em TI.

Crie sua conta

Preencha os dados para iniciar o seu cadastro no plano anual do Clube de Estudos:

Crie sua conta

Preencha os dados para iniciar o seu cadastro no plano mensal do Clube de Estudos:

× Precisa de ajuda?