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:

What kind of optimizations could we expect from the C# compiler and the JIT? In this post, I would like...
Há algum tempo, estou compartilhando recomendações práticas para construção de microsserviços com Aspnet Core.  Agora, resolvi organizar meus exemplos para...
Há quase um mês, resolvi intensificar a comunicação da EximiaCo, dessa vez, em um canal dedicado ao público técnico, no...
Quando estamos desenvolvendo aplicações distribuídas, não devemos nos perguntar se teremos problemas de conectividade. No lugar disso, devemos nos perguntar...
This is another post about how to implement a basic Search Engine. Previously, I explained: how to produce an inverted...
Neste post, vamos escrever um Storage Provider para ASP.NET Core Identity, do zero, utilizando RavenDB como mecanismo de persistência. O...
Oferta de pré-venda!

Mentoria em
Arquitetura de Software

Práticas, padrões & técnicas para Arquitetura de Software, de maneira efetiva, com base em cenários reais para profissionais envolvidos no projeto e implantação de software.

× Precisa de ajuda?