public IndexPropertyBatcher(DocumentDatabase database, IndexedPropertiesSetupDoc setupDoc, string index, AbstractViewGenerator viewGenerator)
 {
     this.database      = database;
     this.setupDoc      = setupDoc;
     this.index         = index;
     this.viewGenerator = viewGenerator;
 }
Example #2
0
        private void ExecuteTest(IDocumentStore store)
        {
            var customer1 = new Customer {
                Name = "Matt", Country = "UK"
            };
            var customer2 = new Customer {
                Name = "Debs", Country = "UK"
            };
            var customer3 = new Customer {
                Name = "Bob", Country = "USA"
            };

            using (var session = store.OpenSession())
            {
                session.Store(customer1);
                session.Store(customer2);
                session.Store(customer3);
                session.SaveChanges();
            }
            var customerDocIds = new[] { customer1.Id, customer2.Id, customer3.Id };

            //Orders for Customer1
            var order1 = new Order {
                CustomerId = customer1.Id, Cost = 9.99m
            };
            var order2 = new Order {
                CustomerId = customer1.Id, Cost = 12.99m
            };
            var order3 = new Order {
                CustomerId = customer1.Id, Cost = 1.25m
            };
            //Orders for Customer2
            var order4 = new Order {
                CustomerId = customer2.Id, Cost = 99.99m
            };
            var order5 = new Order {
                CustomerId = customer2.Id, Cost = 105.99m
            };
            //Orders for Customer3
            var order6 = new Order {
                CustomerId = customer3.Id, Cost = 0.05m
            };
            var order7 = new Order {
                CustomerId = customer3.Id, Cost = 0.99m
            };
            var order8 = new Order {
                CustomerId = customer3.Id, Cost = 1.99m
            };

            using (var session = store.OpenSession())
            {
                session.Store(order1);
                session.Store(order2);
                session.Store(order3);

                session.Store(order4);
                session.Store(order5);

                session.Store(order6);
                session.Store(order7);
                session.Store(order8);

                session.SaveChanges();
            }

            var setupDoc = new IndexedPropertiesSetupDoc
            {
                //This is the name of the field in the Map/Reduce results that holds to Id of
                //the documents that we need to write the values back into
                DocumentKey = "CustomerId",

                //This contains the mappings from the Map/Reduce result back to the original doc
                FieldNameMappings =
                {
                    { "Average", "AverageOrderCost" },
                    { "Count",   "NumberOfOrders"   }
                }
            };

            var indexName = new Orders_ByCustomer_Count().IndexName;

            using (var session = store.OpenSession())
            {
                session.Store(setupDoc, IndexedPropertiesSetupDoc.IdPrefix + indexName);
                session.SaveChanges();
            }
            WaitForIndexToUpdate(store, indexName);

            //Test 1 - Check that the averages are written back to the customer docs
            var customerDocs = GetCustomerDocs(store, customerDocIds);

            Assert.Equal((order1.Cost + order2.Cost + order3.Cost) / 3.0m, customerDocs[0].AverageOrderCost, 10);
            Assert.Equal(3, customerDocs[0].NumberOfOrders);
            Assert.Equal((order4.Cost + order5.Cost) / 2.0m, customerDocs[1].AverageOrderCost, 10);
            Assert.Equal(2, customerDocs[1].NumberOfOrders);
            Assert.Equal((order6.Cost + order7.Cost + order8.Cost) / 3.0m, customerDocs[2].AverageOrderCost, 10);
            Assert.Equal(3, customerDocs[2].NumberOfOrders);

            //Test 2 - delete some of the orders for 2 of the customers and check the averages update
            store.DatabaseCommands.Delete(order1.Id, null);
            store.DatabaseCommands.Delete(order8.Id, null);
            WaitForIndexToUpdate(store, indexName);

            customerDocs = GetCustomerDocs(store, customerDocIds);
            Assert.Equal((order2.Cost + order3.Cost) / 2.0m, customerDocs[0].AverageOrderCost, 10);
            Assert.Equal(2, customerDocs[0].NumberOfOrders);
            Assert.Equal((order4.Cost + order5.Cost) / 2.0m, customerDocs[1].AverageOrderCost, 10);
            Assert.Equal(2, customerDocs[1].NumberOfOrders);
            Assert.Equal((order6.Cost + order7.Cost) / 2.0m, customerDocs[2].AverageOrderCost, 10);
            Assert.Equal(2, customerDocs[2].NumberOfOrders);

            //Test 3 - Delete all the orders for customer1, it now has NO orders!
            store.DatabaseCommands.Delete(order2.Id, null);
            store.DatabaseCommands.Delete(order3.Id, null);
            WaitForIndexToUpdate(store, indexName);

            var customer1Json = store.DatabaseCommands.Get(customer1.Id);

            Assert.False(customer1Json.DataAsJson.ContainsKey("AverageOrderCost"));
            Assert.False(customer1Json.DataAsJson.ContainsKey("NumberOfOrders"));

            //Test 4 - Modify the orders for customer2, it's average should update
            using (var session = store.OpenSession())
            {
                var orders = session.Load <Order>(new[] { order4.Id, order5.Id });
                orders[0].Cost = 75.8m;
                orders[1].Cost = 26.1m;
                session.SaveChanges();
            }
            WaitForIndexToUpdate(store, indexName);

            customerDocs = GetCustomerDocs(store, customerDocIds);
            Assert.Equal((75.8m + 26.1m) / 2.0m, customerDocs[1].AverageOrderCost, 10);
            Assert.Equal(2, customerDocs[1].NumberOfOrders);

            //Test 5 - Can actually do the queries we'd like to, i.e. query against customers using the AverageOrderCost field
            using (var session = store.OpenSession())
            {
                RavenQueryStatistics stats;
                var customerByTotalOrderCose = session.Query <Customer>()
                                               .OrderBy(x => x.AverageOrderCost)
                                               .Customize(x => x.WaitForNonStaleResults())
                                               .Statistics(out stats)
                                               .ToList();
                var previous = Decimal.MinValue;
                foreach (var customer in customerByTotalOrderCose)
                {
                    Assert.True(customer.AverageOrderCost > previous);
                    previous = customer.AverageOrderCost;
                }
            }
        }