如何在RavenDb中按相关文档字段创建搜索索引?

如何在RavenDb中按相关文档字段创建搜索索引?,ravendb,Ravendb,我认为我的场景在任何应用程序中都是常见的场景。我将举例说明使用一个常用的领域:产品和订单的项目(的产品) 考虑到订单中有一个ITEN列表,并且每个项目都有一个相关的productId,我试图通过产品名称搜索订单 我做了一些搜索并阅读了Raven文档,但我找不到问题的答案 请考虑下面的代码: public class Product { public string Id { get; set; } public string ProductName { g

我认为我的场景在任何应用程序中都是常见的场景。我将举例说明使用一个常用的领域:产品和订单的项目(的产品)

考虑到订单中有一个ITEN列表,并且每个项目都有一个相关的productId,我试图通过产品名称搜索订单

我做了一些搜索并阅读了Raven文档,但我找不到问题的答案

请考虑下面的代码:

 public class Product
    {
        public string Id { get; set; }
        public string ProductName { get; set; }
        public decimal Price { get; set; }
    }

    public class Order
    {
        public string Id { get; set; }
        public string OrderNumber { get; set; }
        public decimal Total { get; set; }
        public string Customer { get; set; }
        public Item[] Items { get; set; }
    }

    public class Item
    {
        public string ProductId { get; set; }
        public decimal Price { get; set; }
        public int Quantity { get; set; }
    }


    public class Order_ByProductName : AbstractMultiMapIndexCreationTask<Order_ByProductName.Result>
    {
        public class Result
        {
            public string ProductId { get; set; }
            public string ProductName { get; set; }
            public string[] OrdersIds { get; set; }
            public string[] OrdersNumbers { get; set; }
        }

        public Order_ByProductName()
        {
            AddMap<Product>(products => from product in products
                                        select new
                                        {
                                            ProductId = product.Id,
                                            ProductName = product.ProductName,
                                            OrderId = default(string),
                                            OrderNumber = default(string)
                                        });

            AddMap<Order>(orders => from order in orders
                                    group order by order.Items.Select(c => c.ProductId)
                                    into g
                                    select new
                                    {
                                        ProductId = g.Key,
                                        ProductName = default(string),
                                        OrdersIds = g.Select(c => c.Id),
                                        OrdersNumbers = g.Select(c => c.OrderNumber)
                                    });

            Reduce = results => from result in results
                                group result by result.ProductId
                                into g
                                select new
                                {
                                    ProductId = g.Key,
                                    ProductName = g.Select(r => r.ProductName).Where(t => t != null).First(),
                                    OrdersIds = g.Where(r => r.OrdersIds != null).SelectMany(r => r.OrdersIds),
                                    OrdersNumbers = g.Where(r => r.OrdersNumbers != null).SelectMany(r => r.OrdersNumbers)
                                };

            Sort("ProductName", SortOptions.String);
            Index(x => x.ProductName, FieldIndexing.Analyzed);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var documentStore = new DocumentStore
            {
                Url = "http://localhost:8080",
                DefaultDatabase = "MyDatabase"
            };

            documentStore.Initialize();
            new Order_ByProductName().Execute(documentStore);

            using (var session = documentStore.OpenSession())
            {
                var product1 = new Product() { Price = 100, ProductName = "Phone" };
                var product2 = new Product() { Price = 1000, ProductName = "Laptop" };
                var product3 = new Product() { Price = 200, ProductName = "Windows Phone" };

                session.Store(product1);
                session.Store(product2);
                session.Store(product3);
                session.SaveChanges();
            }

            using (var session = documentStore.OpenSession())
            {
                var products = session.Query<Product>().ToList();

                var order1 = new Order();
                order1.Customer = "Jhon Doe";
                order1.OrderNumber = "001";
                order1.Items = new Item[] {
                    new Item { ProductId = products[0].Id, Price = products[0].Price, Quantity = 1 },
                    new Item { ProductId = products[1].Id, Price = products[1].Price, Quantity = 1 }
                };
                order1.Total = order1.Items.Sum(c => (c.Quantity * c.Price));

                var order2 = new Order();
                order2.Customer = "Joan Doe";
                order2.OrderNumber = "002";
                order2.Items = new Item[] {
                    new Item { ProductId = products[2].Id, Price = products[2].Price, Quantity = 1 }
                };
                order2.Total = order2.Items.Sum(c => (c.Quantity * c.Price));

                session.Store(order1);
                session.Store(order2);
                session.SaveChanges();
            }

            using (var session = documentStore.OpenSession())
            {
                var results = session
                    .Query<Order_ByProductName.Result, Order_ByProductName>()
                    .Where(x => x.ProductName == "Phone")
                    .ToList();

                foreach (var item in results)
                {
                    Console.WriteLine($"{item.ProductName}\t{string.Join(", ", item.OrdersNumbers)}");
                }

                Console.ReadKey();
            }
        }
    }
如何通过ProductName创建搜索并在RavenDb中返回列表或订单? Im使用版本3.5(.1)

将主要问题视为“按相关实体属性搜索实体”


提前谢谢

考虑将产品名称直接存储在订单项中。这将有两个好处-订单项不会受到后期产品更改的影响,索引将更便宜

以下代码演示了这两种方法:

public class Product
{
    public string Id { get; set; }
    public string ProductName { get; set; }
    public decimal Price { get; set; }
}

public class Order
{
    public string Id { get; set; }
    public string OrderNumber { get; set; }
    public decimal Total { get; set; }
    public string Customer { get; set; }
    public Item[] Items { get; set; }
}

public class Item
{
    public string ProductId { get; set; }
    public string ProductName { get; set; }
    public decimal Price { get; set; }
    public int Quantity { get; set; }
}

public class OrderView
{
    public string OrderId { get; set; }
    public string OrderNumber { get; set; }
    public string[] ProductIds { get; set; }
    public string[] ProductNames { get; set; }
}

public class Order_ByItemName : AbstractIndexCreationTask<Order, OrderView>
{
    public Order_ByItemName()
    {
        Map = orders => from order in orders
                        select new
                        {
                            OrderId = order.Id,
                            OrderNumber = order.OrderNumber,
                            ProductIds = order.Items.Select(x => x.ProductId).ToArray(),
                            ProductNames = order.Items.Select(x => x.ProductName).ToArray(),
                        };

        Index(x => x.ProductNames, FieldIndexing.Analyzed);
        StoreAllFields(FieldStorage.Yes);
    }
}

public class Order_ByProductName : AbstractIndexCreationTask<Order, OrderView>
{
    public Order_ByProductName()
    {
        Map = orders => from order in orders
                        let products = LoadDocument<Product>(order.Items.Select(x => x.ProductId))
                        select new
                        {
                            OrderId = order.Id,
                            OrderNumber = order.OrderNumber,
                            ProductIds = products.Select(x => x.Id).ToArray(),
                            ProductNames = products.Select(x => x.ProductName).ToArray(),
                        };

        Index(x => x.ProductNames, FieldIndexing.Analyzed);
        StoreAllFields(FieldStorage.Yes);
    }
}

class Program
{

    static void Main(string[] args)
    {
        var documentStore = new DocumentStore
        {
            Url = "http://localhost:8080",
            DefaultDatabase = "MyDatabase"
        };

        documentStore.Initialize();
        new Order_ByProductName().Execute(documentStore);
        new Order_ByItemName().Execute(documentStore);

        using (var session = documentStore.OpenSession())
        {
            var product1 = new Product() { Id = "products/1", Price = 100, ProductName = "Phone" };
            var product2 = new Product() { Id = "products/2", Price = 1000, ProductName = "Laptop" };
            var product3 = new Product() { Id = "products/3", Price = 200, ProductName = "Windows Phone" };

            session.Store(product1);
            session.Store(product2);
            session.Store(product3);
            session.SaveChanges();
        }

        using (var session = documentStore.OpenSession())
        {
            var products = session.Query<Product>().ToList();

            var order1 = new Order();
            order1.Id = "orders/1";
            order1.Customer = "Jhon Doe";
            order1.OrderNumber = "001";
            order1.Items = new Item[] {
                new Item { ProductId = products[0].Id, ProductName = products[0].ProductName, Price = products[0].Price, Quantity = 1 },
                new Item { ProductId = products[1].Id, ProductName = products[1].ProductName, Price = products[1].Price, Quantity = 1 }
            };
            order1.Total = order1.Items.Sum(c => (c.Quantity * c.Price));

            var order2 = new Order();
            order1.Id = "orders/1";
            order2.Customer = "Joan Doe";
            order2.OrderNumber = "002";
            order2.Items = new Item[] {
                new Item { ProductId = products[2].Id, ProductName = products[2].ProductName, Price = products[2].Price, Quantity = 1 }
            };
            order2.Total = order2.Items.Sum(c => (c.Quantity * c.Price));

            session.Store(order1);
            session.Store(order2);
            session.SaveChanges();
        }
        Thread.Sleep(5000); // wait for indexing

        using (var session = documentStore.OpenSession())
        {
            var itemResults = session
                .Query<OrderView, Order_ByItemName>()
                .Search(x => x.ProductNames, "Phone")
                .ProjectFromIndexFieldsInto<OrderView>()
                .ToList();

            var results = session
                .Query<OrderView, Order_ByProductName>()
                .Search(x => x.ProductNames, "Phone")
                .ProjectFromIndexFieldsInto<OrderView>()
                .ToList();


            Console.WriteLine("Order_ByItemName");
            foreach (var order in itemResults)
            {
                Console.WriteLine($"OrderNumber: {order.OrderNumber}");
                for (int i = 0; i < order.ProductIds.Length; i++)
                {
                    Console.WriteLine($"Item: {order.ProductIds[i]} - {order.ProductNames[i]}");
                }
            }

            Console.WriteLine("Order_ByProductName");
            foreach (var order in results)
            {
                Console.WriteLine($"OrderNumber: {order.OrderNumber}");
                for (int i = 0; i < order.ProductIds.Length; i++)
                {
                    Console.WriteLine($"Item: {order.ProductIds[i]} - {order.ProductNames[i]}");
                }
            }

            Console.ReadKey();
        }
    }
}
公共类产品
{
公共字符串Id{get;set;}
公共字符串ProductName{get;set;}
公共十进制价格{get;set;}
}
公共阶级秩序
{
公共字符串Id{get;set;}
公共字符串OrderNumber{get;set;}
公共十进制总数{get;set;}
公共字符串Customer{get;set;}
公共项[]项{get;set;}
}
公共类项目
{
公共字符串ProductId{get;set;}
公共字符串ProductName{get;set;}
公共十进制价格{get;set;}
公共整数数量{get;set;}
}
公共类OrderView
{
公共字符串OrderId{get;set;}
公共字符串OrderNumber{get;set;}
公共字符串[]ProductIds{get;set;}
公共字符串[]产品名称{get;set;}
}
公共类Order_ByItemName:AbstractIndexCreationTask
{
公共秩序_ByItemName()
{
Map=orders=>来自订单中的订单
选择新的
{
OrderId=order.Id,
OrderNumber=order.OrderNumber,
ProductId=order.Items.Select(x=>x.ProductId.ToArray(),
ProductNames=order.Items.Select(x=>x.ProductName.ToArray(),
};
索引(x=>x.ProductNames,FieldIndexing.Analysis);
StoreAllFields(FieldStorage.Yes);
}
}
公共类顺序\u ByProductName:AbstractIndexCreationTask
{
公共秩序\u ByProductName()
{
Map=orders=>来自订单中的订单
让products=LoadDocument(order.Items.Select(x=>x.ProductId))
选择新的
{
OrderId=order.Id,
OrderNumber=order.OrderNumber,
productId=products.Select(x=>x.Id).ToArray(),
ProductName=products。选择(x=>x.ProductName)。ToArray(),
};
索引(x=>x.ProductNames,FieldIndexing.Analysis);
StoreAllFields(FieldStorage.Yes);
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var documentStore=新的documentStore
{
Url=”http://localhost:8080",
DefaultDatabase=“MyDatabase”
};
初始化();
新订单\u ByProductName().Execute(documentStore);
新订单_ByItemName().Execute(documentStore);
使用(var session=documentStore.OpenSession())
{
var product1=new Product(){Id=“products/1”,Price=100,ProductName=“Phone”};
var product2=new Product(){Id=“products/2”,Price=1000,ProductName=“Laptop”};
var product3=new Product(){Id=“products/3”,Price=200,ProductName=“Windows Phone”};
session.Store(product1);
session.Store(product2);
session.Store(product3);
session.SaveChanges();
}
使用(var session=documentStore.OpenSession())
{
var products=session.Query().ToList();
var order1=新订单();
order1.Id=“orders/1”;
订单1.Customer=“Jhon Doe”;
order1.OrderNumber=“001”;
order1.Items=新项目[]{
新项目{ProductId=products[0]。Id,ProductName=products[0]。ProductName,Price=products[0]。Price,QUOTE=1},
新项目{ProductId=products[1]。Id,ProductName=products[1]。ProductName,Price=products[1]。价格,数量=1}
};
order1.Total=order1.Items.Sum(c=>(c.数量*c.价格));
var order2=新订单();
order1.Id=“orders/1”;
订单2.Customer=“Joan Doe”;
order2.OrderNumber=“002”;
order2.Items=新项目[]{
新项目{ProductId=products[2]。Id,ProductName=products[2]。ProductName,Price=products[2]。价格,数量=1}
};
order2.Total=order2.Items.Sum(c=>(c.数量*c.价格));
session.Store(order1);
session.Store(order2);
session.SaveChanges();
}
Thread.Sleep(5000);//等待索引
使用(var session=documentStore.OpenSession())
{
var itemResults=会话
.Query()
.Search(x=>x.ProductNames,“手机”)
.ProjectFromIndexFieldsInto()项目
.ToList();
var结果=会话
.Query()
.Search(x=>x.ProductNames,“手机”)
.ProjectFromIndexFieldsInto()项目
.ToList();
Console.WriteLine(“Order_ByItemName”);
foreach(itemResults中的变量顺序)
{
WriteLine($“OrderNumber:{order.OrderNumber}”);
for(int i=0;ipublic class Product
{
    public string Id { get; set; }
    public string ProductName { get; set; }
    public decimal Price { get; set; }
}

public class Order
{
    public string Id { get; set; }
    public string OrderNumber { get; set; }
    public decimal Total { get; set; }
    public string Customer { get; set; }
    public Item[] Items { get; set; }
}

public class Item
{
    public string ProductId { get; set; }
    public string ProductName { get; set; }
    public decimal Price { get; set; }
    public int Quantity { get; set; }
}

public class OrderView
{
    public string OrderId { get; set; }
    public string OrderNumber { get; set; }
    public string[] ProductIds { get; set; }
    public string[] ProductNames { get; set; }
}

public class Order_ByItemName : AbstractIndexCreationTask<Order, OrderView>
{
    public Order_ByItemName()
    {
        Map = orders => from order in orders
                        select new
                        {
                            OrderId = order.Id,
                            OrderNumber = order.OrderNumber,
                            ProductIds = order.Items.Select(x => x.ProductId).ToArray(),
                            ProductNames = order.Items.Select(x => x.ProductName).ToArray(),
                        };

        Index(x => x.ProductNames, FieldIndexing.Analyzed);
        StoreAllFields(FieldStorage.Yes);
    }
}

public class Order_ByProductName : AbstractIndexCreationTask<Order, OrderView>
{
    public Order_ByProductName()
    {
        Map = orders => from order in orders
                        let products = LoadDocument<Product>(order.Items.Select(x => x.ProductId))
                        select new
                        {
                            OrderId = order.Id,
                            OrderNumber = order.OrderNumber,
                            ProductIds = products.Select(x => x.Id).ToArray(),
                            ProductNames = products.Select(x => x.ProductName).ToArray(),
                        };

        Index(x => x.ProductNames, FieldIndexing.Analyzed);
        StoreAllFields(FieldStorage.Yes);
    }
}

class Program
{

    static void Main(string[] args)
    {
        var documentStore = new DocumentStore
        {
            Url = "http://localhost:8080",
            DefaultDatabase = "MyDatabase"
        };

        documentStore.Initialize();
        new Order_ByProductName().Execute(documentStore);
        new Order_ByItemName().Execute(documentStore);

        using (var session = documentStore.OpenSession())
        {
            var product1 = new Product() { Id = "products/1", Price = 100, ProductName = "Phone" };
            var product2 = new Product() { Id = "products/2", Price = 1000, ProductName = "Laptop" };
            var product3 = new Product() { Id = "products/3", Price = 200, ProductName = "Windows Phone" };

            session.Store(product1);
            session.Store(product2);
            session.Store(product3);
            session.SaveChanges();
        }

        using (var session = documentStore.OpenSession())
        {
            var products = session.Query<Product>().ToList();

            var order1 = new Order();
            order1.Id = "orders/1";
            order1.Customer = "Jhon Doe";
            order1.OrderNumber = "001";
            order1.Items = new Item[] {
                new Item { ProductId = products[0].Id, ProductName = products[0].ProductName, Price = products[0].Price, Quantity = 1 },
                new Item { ProductId = products[1].Id, ProductName = products[1].ProductName, Price = products[1].Price, Quantity = 1 }
            };
            order1.Total = order1.Items.Sum(c => (c.Quantity * c.Price));

            var order2 = new Order();
            order1.Id = "orders/1";
            order2.Customer = "Joan Doe";
            order2.OrderNumber = "002";
            order2.Items = new Item[] {
                new Item { ProductId = products[2].Id, ProductName = products[2].ProductName, Price = products[2].Price, Quantity = 1 }
            };
            order2.Total = order2.Items.Sum(c => (c.Quantity * c.Price));

            session.Store(order1);
            session.Store(order2);
            session.SaveChanges();
        }
        Thread.Sleep(5000); // wait for indexing

        using (var session = documentStore.OpenSession())
        {
            var itemResults = session
                .Query<OrderView, Order_ByItemName>()
                .Search(x => x.ProductNames, "Phone")
                .ProjectFromIndexFieldsInto<OrderView>()
                .ToList();

            var results = session
                .Query<OrderView, Order_ByProductName>()
                .Search(x => x.ProductNames, "Phone")
                .ProjectFromIndexFieldsInto<OrderView>()
                .ToList();


            Console.WriteLine("Order_ByItemName");
            foreach (var order in itemResults)
            {
                Console.WriteLine($"OrderNumber: {order.OrderNumber}");
                for (int i = 0; i < order.ProductIds.Length; i++)
                {
                    Console.WriteLine($"Item: {order.ProductIds[i]} - {order.ProductNames[i]}");
                }
            }

            Console.WriteLine("Order_ByProductName");
            foreach (var order in results)
            {
                Console.WriteLine($"OrderNumber: {order.OrderNumber}");
                for (int i = 0; i < order.ProductIds.Length; i++)
                {
                    Console.WriteLine($"Item: {order.ProductIds[i]} - {order.ProductNames[i]}");
                }
            }

            Console.ReadKey();
        }
    }
}