Example #1
0
		public void HandleResponses(GetResponse[] responses, ShardStrategy shardStrategy)
		{
			var list = new List<MultiLoadResult>(
				from response in responses
				let result = response.Result
				select new MultiLoadResult
				{
					Includes = result.Value<RavenJArray>("Includes").Cast<RavenJObject>().ToList(),
					Results = result.Value<RavenJArray>("Results").Cast<RavenJObject>().ToList()
				});

			var capacity = list.Max(x => x.Results.Count);

			var finalResult = new MultiLoadResult
			                  	{
									Includes = new List<RavenJObject>(),
			                  		Results = new List<RavenJObject>(Enumerable.Range(0,capacity).Select(x=> (RavenJObject)null))
			                  	};


			foreach (var multiLoadResult in list)
			{
				finalResult.Includes.AddRange(multiLoadResult.Includes);

				for (int i = 0; i < multiLoadResult.Results.Count; i++)
				{
					if (finalResult.Results[i] == null)
						finalResult.Results[i] = multiLoadResult.Results[i];
				}
			}
			RequiresRetry = loadOperation.SetResult(finalResult);
			if (RequiresRetry == false)
				Result = loadOperation.Complete<T>();

		}
Example #2
0
		public override void Respond(IHttpContext context)
		{
			RavenJArray itemsToLoad;
			if(context.Request.HttpMethod == "POST")
				itemsToLoad = context.ReadJsonArray();
			else
				itemsToLoad = new RavenJArray(context.Request.QueryString.GetValues("id"));
			var result = new MultiLoadResult();
			var loadedIds = new HashSet<string>();
			var includes = context.Request.QueryString.GetValues("include") ?? new string[0];
			var transactionInformation = GetRequestTransaction(context);
		    var includedEtags = new List<byte>();
			Database.TransactionalStorage.Batch(actions =>
			{
				foreach (RavenJToken item in itemsToLoad)
				{
					var value = item.Value<string>();
					if(loadedIds.Add(value)==false)
						continue;
					var documentByKey = Database.Get(value, transactionInformation);
					if (documentByKey == null)
						continue;
					result.Results.Add(documentByKey.ToJson());

					if (documentByKey.Etag != null)
					{
						includedEtags.AddRange(documentByKey.Etag.Value.ToByteArray());
					}
					includedEtags.Add((documentByKey.NonAuthoritativeInformation ?? false) ? (byte)0 : (byte)1);
				}

				var addIncludesCommand = new AddIncludesCommand(Database, transactionInformation, (etag, includedDoc) =>
				{
					includedEtags.AddRange(etag.ToByteArray());
					result.Includes.Add(includedDoc);
				}, includes, loadedIds);

				foreach (var item in result.Results.Where(item => item != null))
				{
					addIncludesCommand.Execute(item);
				}
			});

			Guid computedEtag;

			using (var md5 = MD5.Create())
			{
				var computeHash = md5.ComputeHash(includedEtags.ToArray());
				computedEtag = new Guid(computeHash);
			}

			if (context.MatchEtag(computedEtag))
			{
				context.SetStatusToNotModified();
				return;
			}

			context.WriteETag(computedEtag);
			context.WriteJson(result);
		}
Example #3
0
        /// <summary>
        /// Gets the results for the specified ids.
        /// </summary>
        /// <param name="ids">The ids.</param>
        /// <param name="includes">The includes.</param>
        /// <param name="metadataOnly">Load just the document metadata</param>
        /// <returns></returns>
        public MultiLoadResult Get(string[] ids, string[] includes, bool metadataOnly = false)
        {
            CurrentOperationContext.Headers.Value = OperationsHeaders;

            // metadata only is not supported for embedded

            var multiLoadResult = new MultiLoadResult
            {
                Results = ids
                          .Select(id => database.Get(id, TransactionInformation))
                          .ToArray()
                          .Select(x => x == null ? null : x.ToJson())
                          .ToList(),
            };

            if (includes != null)
            {
                var includeCmd = new AddIncludesCommand(database, TransactionInformation, (etag, doc) => multiLoadResult.Includes.Add(doc), includes,
                                                        new HashSet <string>(ids));
                foreach (var jsonDocument in multiLoadResult.Results)
                {
                    includeCmd.Execute(jsonDocument);
                }
            }

            return(multiLoadResult);
        }
Example #4
0
        public Get()
        {
            using (var store = new DocumentStore())
            {
                #region get_1_2
                JsonDocument document = store.DatabaseCommands.Get("products/1");                 // null if does not exist
                #endregion

                #region get_2_2
                MultiLoadResult resultsWithoutIncludes = store
                                                         .DatabaseCommands
                                                         .Get(new[] { "products/1", "products/2" }, null);
                #endregion

                #region get_2_3
                MultiLoadResult resultsWithIncludes = store
                                                      .DatabaseCommands
                                                      .Get(
                    new[] { "products/1", "products/2" },
                    new[] { "Category" });

                List <RavenJObject> results  = resultsWithIncludes.Results;               // products/1, products/2
                List <RavenJObject> includes = resultsWithIncludes.Includes;              // categories/1
                #endregion
            }
        }
        public TransformQueryResults()
        {
            using (var store = new DocumentStore())
            {
                #region query_transformer_1
                // query for all orders with 'Company' equal to 'companies/1' using 'Orders/Totals' index
                // and transform results using 'Order/Statistics' transformer
                QueryResult result = store
                                     .DatabaseCommands
                                     .Query(
                    "Orders/Totals",
                    new IndexQuery
                {
                    Query = "Company:companies/1",
                    ResultsTransformer = "Order/Statistics"
                });
                #endregion
            }

            using (var store = new DocumentStore())
            {
                #region query_transformer_2
                // query for all orders with 'Company' equal to 'companies/1' using 'Orders/Totals' index
                // and transform results using 'Order/Statistics' transformer
                // stream the results
                QueryHeaderInformation     queryHeaderInfo;
                IEnumerator <RavenJObject> result = store
                                                    .DatabaseCommands
                                                    .StreamQuery(
                    "Orders/Totals",
                    new IndexQuery
                {
                    Query = "Company:companies/1",
                    ResultsTransformer = "Order/Statistics"
                },
                    out queryHeaderInfo);
                #endregion
            }

            using (var store = new DocumentStore())
            {
                #region query_transformer_3
                // Search for similar documents to 'articles/1'
                // using 'Articles/MoreLikeThis' index, search only field 'Body'
                // and transform results using 'Articles/NoComments' transformer
                QueryHeaderInformation queryHeaderInfo;
                MultiLoadResult        result = store
                                                .DatabaseCommands
                                                .MoreLikeThis(
                    new MoreLikeThisQuery
                {
                    IndexName          = "Articles/MoreLikeThis",
                    DocumentId         = "articles/1",
                    Fields             = new[] { "Body" },
                    ResultsTransformer = "Articles/NoComments"
                });
                #endregion
            }
        }
Example #6
0
 private void HandleResponse(MultiLoadResult multiLoadResult)
 {
     RequiresRetry = multiLoadOperation.SetResult(multiLoadResult);
     if (RequiresRetry == false)
     {
         Result = multiLoadOperation.Complete <T>();
     }
 }
Example #7
0
        public bool SetResult(MultiLoadResult multiLoadResult)
        {
            firstRequest   = false;
            includeResults = SerializationHelper.RavenJObjectsToJsonDocuments(multiLoadResult.Includes).ToArray();
            results        = SerializationHelper.RavenJObjectsToJsonDocuments(multiLoadResult.Results).ToArray();

            return(sessionOperations.AllowNonAuthoritativeInformation == false &&
                   results.Where(x => x != null).Any(x => x.NonAuthoritativeInformation ?? false) &&
                   sp.Elapsed < sessionOperations.NonAuthoritativeInformationTimeout);
        }
Example #8
0
		public void HandleResponse(GetResponse response)
		{
			var result = response.Result;

			var multiLoadResult = new MultiLoadResult
			{
				Includes = result.Value<RavenJArray>("Includes").Cast<RavenJObject>().ToList(),
				Results = result.Value<RavenJArray>("Results").Cast<RavenJObject>().ToList()
			};
			HandleResponse(multiLoadResult);
		}
        private void HandleRespose(MultiLoadResult multiLoadResult)
        {
            T[] complete = loadTransformerOperation.Complete <T>(multiLoadResult);
            if (singleResult)
            {
                Result = complete.Length > 0 ? complete[0] : (object)null;
                return;
            }

            Result = complete;
        }
Example #10
0
        public void HandleResponse(GetResponse response)
        {
            var result = RavenJObject.Parse(response.Result);

            var multiLoadResult = new MultiLoadResult
            {
                Includes = result.Value <RavenJArray>("Includes").Cast <RavenJObject>().ToList(),
                Results  = result.Value <RavenJArray>("Results").Cast <RavenJObject>().ToList()
            };

            RequiresRetry = loadOperation.SetResult(multiLoadResult);
            if (RequiresRetry == false)
            {
                Result = loadOperation.Complete <T>();
            }
        }
        public T[] Complete <T>(MultiLoadResult multiLoadResult)
        {
            foreach (var include in SerializationHelper.RavenJObjectsToJsonDocuments(multiLoadResult.Includes))
            {
                documentSession.TrackIncludedDocument(include);
            }

            if (typeof(T).IsArray)
            {
                var arrayOfArrays = multiLoadResult.Results
                                    .Select(x =>
                {
                    if (x == null)
                    {
                        return(null);
                    }

                    var values = x.Value <RavenJArray>("$values").Cast <RavenJObject>();

                    var elementType = typeof(T).GetElementType();
                    var array       = values.Select(value =>
                    {
                        EnsureNotReadVetoed(value);
                        return(documentSession.ProjectionToInstance(value, elementType));
                    }).ToArray();
                    var newArray = Array.CreateInstance(elementType, array.Length);
                    Array.Copy(array, newArray, array.Length);
                    return(newArray);
                })
                                    .Cast <T>()
                                    .ToArray();

                return(arrayOfArrays);
            }

            var items = ParseResults <T>(multiLoadResult.Results)
                        .ToArray();

            if (items.Length > ids.Length)
            {
                throw new InvalidOperationException(String.Format("A load was attempted with transformer {0}, and more than one item was returned per entity - please use {1}[] as the projection type instead of {1}",
                                                                  transformer,
                                                                  typeof(T).Name));
            }

            return(items);
        }
Example #12
0
        public void MissingDocuments()
        {
            using (var store = new DocumentStore())
            {
                #region get_2_4
                // assuming that 'products/9999' does not exist
                MultiLoadResult resultsWithIncludes = store
                                                      .DatabaseCommands
                                                      .Get(
                    new[] { "products/1", "products/9999", "products/3" },
                    null);

                List <RavenJObject> results  = resultsWithIncludes.Results;               // products/1, null, products/3
                List <RavenJObject> includes = resultsWithIncludes.Includes;              // empty
                #endregion
            }
        }
Example #13
0
        public static void G11_LoadInclude()
        {
            /*
             * Load multiple documents in a single request into session
             */
            using (var session = Store.Documents.OpenSession())
            {
                var products = session.Load <Product>(new[] {
                    "products/77",
                    "products/76"
                });

                /*
                 * Loaded from session, i.e. no additional requests to the server are made
                 */
                var product77 = session.Load <Product>(77);
                var product76 = session.Load <Product>(76);
            }

            /*
             * Load a document and include another document in a single request
             */
            using (var session = Store.Documents.OpenSession())
            {
                var order = session
                            .Include <Order>(o => o.Company)
                            .Load <Order>(826);

                var company = session.Load <Company>(order.Company);
            }

            /*
             * Load a document and include several documents of different datatypes in a single request
             */
            {
                MultiLoadResult result = Store.Documents
                                         .DatabaseCommands
                                         .Get(ids: new[] { "orders/827" }, includes: new[] { "Company", "Employee", "ShipVia" });

                RavenJObject order    = result.Results[0];
                RavenJObject company  = result.Includes[0];
                RavenJObject employee = result.Includes[1];
                RavenJObject shipper  = result.Includes[2];
            }
        }
Example #14
0
        public void HandleResponse(GetResponse response)
        {
            if (response.ForceRetry)
            {
                Result        = null;
                RequiresRetry = true;
                return;
            }

            var result = response.Result;

            var multiLoadResult = new MultiLoadResult
            {
                Includes = result.Value <RavenJArray>("Includes").Cast <RavenJObject>().ToList(),
                Results  = result.Value <RavenJArray>("Results").Select(x => x as RavenJObject).ToList()
            };

            HandleResponse(multiLoadResult);
        }
Example #15
0
        /// <summary>
        /// Gets the results for the specified ids.
        /// </summary>
        /// <param name="ids">The ids.</param>
        /// <param name="includes">The includes.</param>
        /// <returns></returns>
        public MultiLoadResult Get(string[] ids, string[] includes)
        {
            CurrentOperationContext.Headers.Value = OperationsHeaders;

            var multiLoadResult = new MultiLoadResult
            {
                Results = ids
                          .Select(id => database.Get(id, TransactionInformation))
                          .Where(document => document != null)
                          .ToArray()
                          .Select(x => EnsureLocalDate(x).ToJson())
                          .ToList(),
            };
            var includeCmd = new AddIncludesCommand(database, TransactionInformation, (etag, doc) => multiLoadResult.Includes.Add(doc), includes, new HashSet <string>(ids));

            foreach (var jsonDocument in multiLoadResult.Results)
            {
                includeCmd.Execute(jsonDocument);
            }
            return(multiLoadResult);
        }
        protected JsonDocument HandleGetDocumentResult(MultiLoadResult documents)
        {
            if (documents.Results.Count == 2 && documents.Results[1] != null)
            {
                lastServerPrefix = documents.Results[1].Value <string>("ServerPrefix");
            }
            else
            {
                lastServerPrefix = string.Empty;
            }
            if (documents.Results.Count == 0 || documents.Results[0] == null)
            {
                return(null);
            }
            var jsonDocument = documents.Results[0].ToJsonDocument();

            foreach (var key in jsonDocument.Metadata.Keys.Where(x => x.StartsWith("@")).ToArray())
            {
                jsonDocument.Metadata.Remove(key);
            }
            return(jsonDocument);
        }
Example #17
0
        public T[] Complete <T>(MultiLoadResult multiLoadResult)
        {
            if (typeof(T).IsArray)
            {
                // Returns array of arrays, public APIs don't surface that yet though as we only support Transform
                // With a single Id
                var arrayOfArrays = multiLoadResult
                                    .Results
                                    .Select(x => x.Value <RavenJArray>("$values").Cast <RavenJObject>())
                                    .Select(values =>
                {
                    var elementType = typeof(T).GetElementType();
                    var array       = values.Select(y =>
                    {
                        return(documentSession.ProjectionToInstance(y, elementType));
                    }).ToArray();
                    var newArray = Array.CreateInstance(elementType, array.Length);
                    Array.Copy(array, newArray, array.Length);
                    return(newArray);
                })
                                    .Cast <T>()
                                    .ToArray();

                return(arrayOfArrays);
            }

            var items = ParseResults <T>(multiLoadResult.Results)
                        .ToArray();

            if (items.Length > ids.Length)
            {
                throw new InvalidOperationException(String.Format("A load was attempted with transformer {0}, and more than one item was returned per entity - please use {1}[] as the projection type instead of {1}",
                                                                  transformer,
                                                                  typeof(T).Name));
            }

            return(items);
        }
        public HowToWorkWithMoreLikeThisQuery()
        {
            using (var store = new DocumentStore())
            {
                #region more_like_this_2
                // Search for similar documents to 'articles/1'
                // using 'Articles/MoreLikeThis' index and search only field 'Body'
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .MoreLikeThis(
                    new MoreLikeThisQuery
                {
                    IndexName  = "Articles/MoreLikeThis",
                    DocumentId = "articles/1",
                    Fields     = new[] { "Body" }
                });
                #endregion
            }

            using (var store = new DocumentStore())
            {
                #region more_like_this_3
                // Search for similar documents to 'articles/1'
                // using 'Articles/MoreLikeThis' index and search only field 'Body'
                // where article category is 'IT'
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .MoreLikeThis(
                    new MoreLikeThisQuery
                {
                    IndexName       = "Articles/MoreLikeThis",
                    DocumentId      = "articles/1",
                    Fields          = new[] { "Body" },
                    AdditionalQuery = "Category:IT"
                });
                #endregion
            }
        }
Example #19
0
        public override void Respond(IHttpContext context)
        {
            JArray itemsToLoad;

            if (context.Request.HttpMethod == "POST")
            {
                itemsToLoad = context.ReadJsonArray();
            }
            else
            {
                itemsToLoad = new JArray(context.Request.QueryString.GetValues("id"));
            }
            var result    = new MultiLoadResult();
            var loadedIds = new HashSet <string>();
            var includes  = context.Request.QueryString.GetValues("include") ?? new string[0];
            var transactionInformation = GetRequestTransaction(context);
            var includedEtags          = new List <byte>();

            Database.TransactionalStorage.Batch(actions =>
            {
                var addIncludesCommand = new AddIncludesCommand(Database, transactionInformation, (etag, includedDoc) =>
                {
                    includedEtags.AddRange(etag.ToByteArray());
                    result.Includes.Add(includedDoc);
                }, includes, loadedIds);
                foreach (JToken item in itemsToLoad)
                {
                    var value = item.Value <string>();
                    if (loadedIds.Add(value) == false)
                    {
                        continue;
                    }
                    var documentByKey = Database.Get(value, transactionInformation);
                    if (documentByKey == null)
                    {
                        continue;
                    }
                    result.Results.Add(documentByKey.ToJson());

                    includedEtags.AddRange(documentByKey.Etag.ToByteArray());
                    addIncludesCommand.Execute(documentByKey.DataAsJson);
                }
            });

            Guid computedEtag;

            using (var md5 = MD5.Create())
            {
                var computeHash = md5.ComputeHash(includedEtags.ToArray());
                computedEtag = new Guid(computeHash);
            }

            if (context.MatchEtag(computedEtag))
            {
                context.SetStatusToNotModified();
                return;
            }

            context.Response.AddHeader("ETag", computedEtag.ToString());
            context.WriteJson(result);
        }
 private void HandleRespose(MultiLoadResult multiLoadResult)
 {
     T[] complete = loadTransformerOperation.Complete <T>(multiLoadResult);
     Result = singleResult ? (object)complete[0] : complete;
 }
        public void Includes()
        {
            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_1_0
                    Order order = session
                                  .Include <Order>(x => x.CustomerId)
                                  .Load("orders/1234");

                    // this will not require querying the server!
                    Customer customer = session
                                        .Load <Customer>(order.CustomerId);
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_1_1
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .Get(ids: new[] { "orders/1234" }, includes: new[] { "CustomerId" });

                RavenJObject order    = result.Results[0];
                RavenJObject customer = result.Includes[0];
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_2_0
                    Order[] orders = session
                                     .Include <Order>(x => x.CustomerId)
                                     .Load("orders/1234", "orders/4321");

                    foreach (Order order in orders)
                    {
                        // this will not require querying the server!
                        Customer customer = session.Load <Customer>(order.CustomerId);
                    }
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_2_1
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .Get(ids: new[] { "orders/1234", "orders/4321" }, includes: new[] { "CustomerId" });

                List <RavenJObject> orders    = result.Results;
                List <RavenJObject> customers = result.Includes;
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_3_0
                    IList <Order> orders = session
                                           .Query <Order, Orders_ByTotalPrice>()
                                           .Customize(x => x.Include <Order>(o => o.CustomerId))
                                           .Where(x => x.TotalPrice > 100)
                                           .ToList();

                    foreach (Order order in orders)
                    {
                        // this will not require querying the server!
                        Customer customer = session
                                            .Load <Customer>(order.CustomerId);
                    }
                    #endregion
                }

                using (var session = store.OpenSession())
                {
                    #region includes_3_1
                    IList <Order> orders = session
                                           .Advanced
                                           .DocumentQuery <Order, Orders_ByTotalPrice>()
                                           .Include(x => x.CustomerId)
                                           .WhereGreaterThan(x => x.TotalPrice, 100)
                                           .ToList();

                    foreach (Order order in orders)
                    {
                        // this will not require querying the server!
                        Customer customer = session
                                            .Load <Customer>(order.CustomerId);
                    }
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_3_2
                QueryResult result = store
                                     .DatabaseCommands
                                     .Query(
                    "Orders/ByTotalPrice",
                    new IndexQuery
                {
                    Query = "TotalPrice_Range:{Ix100 TO NULL}"
                },
                    includes: new[] { "CustomerId" });

                List <RavenJObject> orders    = result.Results;
                List <RavenJObject> customers = result.Includes;
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_4_0
                    Order order = session
                                  .Include <Order>(x => x.SupplierIds)
                                  .Load("orders/1234");

                    foreach (Guid supplierId in order.SupplierIds)
                    {
                        // this will not require querying the server!
                        Supplier supplier = session.Load <Supplier>(supplierId);
                    }
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_4_1
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .Get(ids: new[] { "orders/1234" }, includes: new[] { "SupplierIds" });

                RavenJObject order    = result.Results[0];
                RavenJObject customer = result.Includes[0];
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_5_0
                    Order[] orders = session
                                     .Include <Order>(x => x.SupplierIds)
                                     .Load("orders/1234", "orders/4321");

                    foreach (Order order in orders)
                    {
                        foreach (Guid supplierId in order.SupplierIds)
                        {
                            // this will not require querying the server!
                            Supplier supplier = session.Load <Supplier>(supplierId);
                        }
                    }
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_5_1
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .Get(ids: new[] { "orders/1234", "orders/4321" }, includes: new[] { "SupplierIds" });

                List <RavenJObject> orders    = result.Results;
                List <RavenJObject> customers = result.Includes;
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_6_0
                    Order order = session
                                  .Include <Order>(x => x.Referral.CustomerId)
                                  .Load("orders/1234");

                    // this will not require querying the server!
                    Customer customer = session.Load <Customer>(order.Referral.CustomerId);
                    #endregion
                }

                using (var session = store.OpenSession())
                {
                    #region includes_6_2
                    Order order = session.Include("Referral.CustomerId")
                                  .Load <Order>("orders/1234");

                    // this will not require querying the server!
                    Customer customer = session.Load <Customer>(order.Referral.CustomerId);
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_6_1
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .Get(ids: new[] { "orders/1234" }, includes: new[] { "Referral.CustomerId" });

                RavenJObject order    = result.Results[0];
                RavenJObject customer = result.Includes[0];
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_7_0
                    Order order = session
                                  .Include <Order>(x => x.LineItems.Select(li => li.ProductId))
                                  .Load("orders/1234");

                    foreach (LineItem lineItem in order.LineItems)
                    {
                        // this will not require querying the server!
                        Product product = session.Load <Product>(lineItem.ProductId);
                    }
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_7_1
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .Get(ids: new[] { "orders/1234" }, includes: new[] { "LineItems.,ProductId" });

                RavenJObject order   = result.Results[0];
                RavenJObject product = result.Includes[0];
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_8_0
                    Order2 order = session
                                   .Include <Order2, Customer2>(x => x.CustomerId)
                                   .Load("order2s/1234");

                    // this will not require querying the server!
                    Customer2 customer = session.Load <Customer2>(order.CustomerId);
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_8_1
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .Get(ids: new[] { "order2s/1234" }, includes: new[] { "CustomerId" });

                RavenJObject order    = result.Results[0];
                RavenJObject customer = result.Includes[0];
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_8_2
                    IList <Order2> orders = session
                                            .Query <Order2, Order2s_ByTotalPrice>()
                                            .Customize(x => x.Include <Order2, Customer2>(o => o.CustomerId))
                                            .Where(x => x.TotalPrice > 100)
                                            .ToList();

                    foreach (Order2 order in orders)
                    {
                        // this will not require querying the server!
                        Customer2 customer = session.Load <Customer2>(order.CustomerId);
                    }
                    #endregion
                }

                using (var session = store.OpenSession())
                {
                    #region includes_8_3
                    IList <Order2> orders = session
                                            .Advanced
                                            .DocumentQuery <Order2, Order2s_ByTotalPrice>()
                                            .Include("CustomerId")
                                            .WhereGreaterThan(x => x.TotalPrice, 100)
                                            .ToList();

                    foreach (Order2 order in orders)
                    {
                        // this will not require querying the server!
                        Customer2 customer = session.Load <Customer2>(order.CustomerId);
                    }
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_8_4
                QueryResult result = store
                                     .DatabaseCommands
                                     .Query(
                    "Order2s/ByTotalPrice",
                    new IndexQuery
                {
                    Query = "TotalPrice_Range:{Ix100 TO NULL}"
                },
                    includes: new[] { "CustomerId" });

                List <RavenJObject> orders    = result.Results;
                List <RavenJObject> customers = result.Includes;
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_8_6
                    Order2 order = session
                                   .Include <Order2, Supplier>(x => x.SupplierIds)
                                   .Load("order2s/1234");

                    foreach (Guid supplierId in order.SupplierIds)
                    {
                        // this will not require querying the server!
                        Supplier supplier = session.Load <Supplier>(supplierId);
                    }
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_8_7
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .Get(ids: new[] { "order2s/1234" }, includes: new[] { "SupplierIds" });

                RavenJObject        order     = result.Results[0];
                List <RavenJObject> suppliers = result.Includes;
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_8_8
                    Order2 order = session
                                   .Include <Order2, Customer2>(x => x.Referral.CustomerId)
                                   .Load("order2s/1234");

                    // this will not require querying the server!
                    Customer2 customer = session.Load <Customer2>(order.Referral.CustomerId);
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_8_9
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .Get(ids: new[] { "order2s/1234" }, includes: new[] { "Referral.CustomerId" });

                RavenJObject order    = result.Results[0];
                RavenJObject customer = result.Includes[0];
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_8_10
                    Order2 order = session
                                   .Include <Order2, Product>(x => x.LineItems.Select(li => li.ProductId))
                                   .Load("orders/1234");

                    foreach (LineItem lineItem in order.LineItems)
                    {
                        // this will not require querying the server!
                        Product product = session.Load <Product>(lineItem.ProductId);
                    }
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_8_11
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .Get(ids: new[] { "order2s/1234" }, includes: new[] { "LineItems.,ProductId" });

                RavenJObject        order    = result.Results[0];
                List <RavenJObject> products = result.Includes;
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_9_0
                    Order3 order = session
                                   .Include <Order3, Customer>(x => x.Customer.Id)
                                   .Load("orders/1234");

                    // this will not require querying the server!
                    Customer customer = session.Load <Customer>(order.Customer.Id);
                    #endregion
                }
            }

            using (var store = new DocumentStore())
            {
                #region includes_9_1
                MultiLoadResult result = store
                                         .DatabaseCommands
                                         .Get(ids: new[] { "orders/1234" }, includes: new[] { "Customer.Id" });

                RavenJObject order    = result.Results[0];
                RavenJObject customer = result.Includes[0];
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_10_0
                    session.Store(
                        new Person
                    {
                        Id         = "people/1",
                        Name       = "John Doe",
                        Attributes = new Dictionary <string, string>
                        {
                            { "Mother", "people/2" },
                            { "Father", "people/3" }
                        }
                    });

                    session.Store(
                        new Person
                    {
                        Id         = "people/2",
                        Name       = "Helen Doe",
                        Attributes = new Dictionary <string, string>()
                    });

                    session.Store(
                        new Person
                    {
                        Id         = "people/3",
                        Name       = "George Doe",
                        Attributes = new Dictionary <string, string>()
                    });
                    #endregion
                }

                using (var session = store.OpenSession())
                {
                    #region includes_10_1
                    var person = session
                                 .Include <Person>(x => x.Attributes.Values)
                                 .Load("people/1");

                    var mother = session
                                 .Load <Person>(person.Attributes["Mother"]);

                    var father = session
                                 .Load <Person>(person.Attributes["Father"]);

                    Assert.Equal(1, session.Advanced.NumberOfRequests);
                    #endregion
                }

                #region includes_10_2
                var result = store
                             .DatabaseCommands
                             .Get(new[] { "people/1" }, new[] { "Attributes.$Values" });

                var include1 = result.Includes[0];
                var include2 = result.Includes[1];
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_10_3
                    var person = session
                                 .Include <Person>(x => x.Attributes.Keys)
                                 .Load("people/1");
                    #endregion
                }

                #region includes_10_4
                var result = store
                             .DatabaseCommands
                             .Get(new[] { "people/1" }, new[] { "Attributes.$Keys" });
                #endregion
            }

            using (var store = new DocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    #region includes_11_0
                    session.Store(
                        new PersonWithAttribute
                    {
                        Id         = "people/1",
                        Name       = "John Doe",
                        Attributes = new Dictionary <string, Attribute>
                        {
                            { "Mother", new Attribute {
                                  Ref = "people/2"
                              } },
                            { "Father", new Attribute {
                                  Ref = "people/3"
                              } }
                        }
                    });

                    session.Store(
                        new Person
                    {
                        Id         = "people/2",
                        Name       = "Helen Doe",
                        Attributes = new Dictionary <string, string>()
                    });

                    session.Store(
                        new Person
                    {
                        Id         = "people/3",
                        Name       = "George Doe",
                        Attributes = new Dictionary <string, string>()
                    });
                    #endregion
                }

                using (var session = store.OpenSession())
                {
                    #region includes_11_1
                    var person = session
                                 .Include <PersonWithAttribute>(x => x.Attributes.Values.Select(v => v.Ref))
                                 .Load("people/1");

                    var mother = session
                                 .Load <Person>(person.Attributes["Mother"].Ref);

                    var father = session
                                 .Load <Person>(person.Attributes["Father"].Ref);

                    Assert.Equal(1, session.Advanced.NumberOfRequests);
                    #endregion
                }

                #region includes_11_2
                var result = store
                             .DatabaseCommands
                             .Get(new[] { "people/1" }, new[] { "Attributes.$Values,Ref" });

                var include1 = result.Includes[0];
                var include2 = result.Includes[1];
                #endregion
            }
        }
Example #22
0
        public MoreLikeThisQueryResult ExecuteMoreLikeThisQuery(MoreLikeThisQuery query, TransactionInformation transactionInformation, int pageSize = 25)
        {
            if (query == null)
            {
                throw new ArgumentNullException("query");
            }

            var index = database.IndexStorage.GetIndexInstance(query.IndexName);

            if (index == null)
            {
                throw new InvalidOperationException("The index " + query.IndexName + " cannot be found");
            }

            if (string.IsNullOrEmpty(query.DocumentId) && query.MapGroupFields.Count == 0)
            {
                throw new InvalidOperationException("The document id or map group fields are mandatory");
            }

            IndexSearcher searcher;

            using (database.IndexStorage.GetCurrentIndexSearcher(index.indexId, out searcher))
            {
                var documentQuery = new BooleanQuery();

                if (string.IsNullOrEmpty(query.DocumentId) == false)
                {
                    documentQuery.Add(new TermQuery(new Term(Constants.DocumentIdFieldName, query.DocumentId.ToLowerInvariant())), Occur.MUST);
                }

                foreach (string key in query.MapGroupFields.Keys)
                {
                    documentQuery.Add(new TermQuery(new Term(key, query.MapGroupFields[key])), Occur.MUST);
                }

                var td = searcher.Search(documentQuery, 1);

                // get the current Lucene docid for the given RavenDB doc ID
                if (td.ScoreDocs.Length == 0)
                {
                    throw new InvalidOperationException("Document " + query.DocumentId + " could not be found");
                }

                var ir  = searcher.IndexReader;
                var mlt = new RavenMoreLikeThis(ir);

                AssignParameters(mlt, query);

                if (string.IsNullOrWhiteSpace(query.StopWordsDocumentId) == false)
                {
                    var stopWordsDoc = database.Documents.Get(query.StopWordsDocumentId, null);
                    if (stopWordsDoc == null)
                    {
                        throw new InvalidOperationException("Stop words document " + query.StopWordsDocumentId + " could not be found");
                    }

                    var stopWordsSetup = stopWordsDoc.DataAsJson.JsonDeserialization <StopWordsSetup>();
                    if (stopWordsSetup.StopWords != null)
                    {
                        var stopWords = stopWordsSetup.StopWords;
                        var ht        = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase);
                        foreach (var stopWord in stopWords)
                        {
                            ht.Add(stopWord);
                        }
                        mlt.SetStopWords(ht);
                    }
                }

                var fieldNames = query.Fields ?? GetFieldNames(ir);
                mlt.SetFieldNames(fieldNames);

                var toDispose = new List <Action>();
                RavenPerFieldAnalyzerWrapper perFieldAnalyzerWrapper = null;
                try
                {
                    perFieldAnalyzerWrapper = index.CreateAnalyzer(new LowerCaseKeywordAnalyzer(), toDispose, true);
                    mlt.Analyzer            = perFieldAnalyzerWrapper;

                    var mltQuery = mlt.Like(td.ScoreDocs[0].Doc);
                    var tsdc     = TopScoreDocCollector.Create(pageSize, true);


                    if (string.IsNullOrWhiteSpace(query.AdditionalQuery) == false)
                    {
                        var additionalQuery = QueryBuilder.BuildQuery(query.AdditionalQuery, perFieldAnalyzerWrapper);
                        mltQuery = new BooleanQuery
                        {
                            { mltQuery, Occur.MUST },
                            { additionalQuery, Occur.MUST },
                        };
                    }

                    searcher.Search(mltQuery, tsdc);
                    var hits          = tsdc.TopDocs().ScoreDocs;
                    var jsonDocuments = GetJsonDocuments(query, searcher, index, query.IndexName, hits, td.ScoreDocs[0].Doc);

                    var result = new MultiLoadResult();

                    var includedEtags = new List <byte>(jsonDocuments.SelectMany(x => x.Etag.ToByteArray()));
                    includedEtags.AddRange(database.Indexes.GetIndexEtag(query.IndexName, null).ToByteArray());
                    var loadedIds          = new HashSet <string>(jsonDocuments.Select(x => x.Key));
                    var addIncludesCommand = new AddIncludesCommand(database, transactionInformation, (etag, includedDoc) =>
                    {
                        includedEtags.AddRange(etag.ToByteArray());
                        result.Includes.Add(includedDoc);
                    }, query.Includes ?? new string[0], loadedIds);

                    idsToLoad = new HashSet <string>();

                    database.TransactionalStorage.Batch(actions =>
                    {
                        documentRetriever = new DocumentRetriever(database.Configuration, actions, database.ReadTriggers, query.TransformerParameters, idsToLoad);

                        using (new CurrentTransformationScope(database, documentRetriever))
                        {
                            foreach (var document in ProcessResults(query, jsonDocuments, database.WorkContext.CancellationToken))
                            {
                                result.Results.Add(document);
                                addIncludesCommand.Execute(document);
                            }
                        }
                    });

                    addIncludesCommand.AlsoInclude(idsToLoad);

                    var  computeHash  = Encryptor.Current.Hash.Compute16(includedEtags.ToArray());
                    Etag computedEtag = Etag.Parse(computeHash);

                    return(new MoreLikeThisQueryResult
                    {
                        Etag = computedEtag,
                        Result = result,
                    });
                }
                finally
                {
                    if (perFieldAnalyzerWrapper != null)
                    {
                        perFieldAnalyzerWrapper.Close();
                    }
                    foreach (var action in toDispose)
                    {
                        action();
                    }
                }
            }
        }
        private async Task <HttpResponseMessage> GetQueriesResponse(bool isGet)
        {
            RavenJArray itemsToLoad;

            if (isGet == false)
            {
                try
                {
                    itemsToLoad = await ReadJsonArrayAsync().ConfigureAwait(false);
                }
                catch (InvalidOperationException e)
                {
                    if (Log.IsDebugEnabled)
                    {
                        Log.DebugException("Failed to deserialize query request.", e);
                    }
                    return(GetMessageWithObject(new
                    {
                        Message = "Could not understand json, please check its validity."
                    }, (HttpStatusCode)422)); //http code 422 - Unprocessable entity
                }
                catch (InvalidDataException e)
                {
                    if (Log.IsDebugEnabled)
                    {
                        Log.DebugException("Failed to deserialize query request.", e);
                    }
                    return(GetMessageWithObject(new
                    {
                        e.Message
                    }, (HttpStatusCode)422)); //http code 422 - Unprocessable entity
                }

                AddRequestTraceInfo(sb =>
                {
                    foreach (var item in itemsToLoad)
                    {
                        sb.Append("\t").Append(item).AppendLine();
                    }
                });
            }
            else
            {
                itemsToLoad = new RavenJArray(GetQueryStringValues("id").Cast <object>());
            }

            var result                 = new MultiLoadResult();
            var loadedIds              = new HashSet <string>();
            var includedIds            = new HashSet <string>();
            var includes               = GetQueryStringValues("include") ?? new string[0];
            var transformer            = GetQueryStringValue("transformer") ?? GetQueryStringValue("resultTransformer");
            var transformerParameters  = this.ExtractTransformerParameters();
            var transactionInformation = GetRequestTransaction();
            var includedEtags          = new List <byte>();

            if (string.IsNullOrEmpty(transformer) == false)
            {
                var transformerDef = Database.IndexDefinitionStorage.GetTransformer(transformer);
                if (transformerDef == null)
                {
                    return(GetMessageWithObject(new { Error = "No such transformer: " + transformer }, HttpStatusCode.BadRequest));
                }
                includedEtags.AddRange(transformerDef.GetHashCodeBytes());
            }

            Database.TransactionalStorage.Batch(actions =>
            {
                foreach (RavenJToken item in itemsToLoad)
                {
                    var value = item.Value <string>();
                    if (loadedIds.Add(value) == false)
                    {
                        continue;
                    }
                    var documentByKey = string.IsNullOrEmpty(transformer)
                                        ? Database.Documents.Get(value, transactionInformation)
                                        : Database.Documents.GetWithTransformer(value, transformer, transactionInformation, transformerParameters, out includedIds);
                    if (documentByKey == null)
                    {
                        if (ClientIsV3OrHigher(Request))
                        {
                            result.Results.Add(null);
                        }
                        continue;
                    }
                    result.Results.Add(documentByKey.ToJson());

                    if (documentByKey.Etag != null)
                    {
                        includedEtags.AddRange(documentByKey.Etag.ToByteArray());
                    }

                    includedEtags.Add((documentByKey.NonAuthoritativeInformation ?? false) ? (byte)0 : (byte)1);
                }

                var addIncludesCommand = new AddIncludesCommand(Database, transactionInformation, (etag, includedDoc) =>
                {
                    includedEtags.AddRange(etag.ToByteArray());
                    result.Includes.Add(includedDoc);
                }, includes, loadedIds);

                foreach (var item in result.Results.Where(item => item != null))
                {
                    addIncludesCommand.Execute(item);
                }
            });


            foreach (var includedId in includedIds)
            {
                var doc = Database.Documents.Get(includedId, transactionInformation);
                if (doc == null)
                {
                    continue;
                }
                includedEtags.AddRange(doc.Etag.ToByteArray());
                result.Includes.Add(doc.ToJson());
            }

            var  computeHash  = Encryptor.Current.Hash.Compute16(includedEtags.ToArray());
            Etag computedEtag = Etag.Parse(computeHash);

            if (MatchEtag(computedEtag))
            {
                return(GetEmptyMessage(HttpStatusCode.NotModified));
            }

            var msg = GetMessageWithObject(result);

            WriteETag(computedEtag, msg);

            AddRequestTraceInfo(sb => sb.AppendFormat("Results count: {0}, includes count: {1}", result.Results.Count, result.Includes.Count).AppendLine());

            return(msg);
        }
Example #24
0
		private async Task<HttpResponseMessage> GetQueriesResponse(bool isGet)
		{
			RavenJArray itemsToLoad;
		    if (isGet == false)
		    {
		        itemsToLoad = await ReadJsonArrayAsync();
                AddRequestTraceInfo(sb =>
                {
                    foreach (var item in itemsToLoad)
                    {
                        sb.Append("\t").Append(item).AppendLine();
                    }
                });
		    }
		    else
		    {
		        itemsToLoad = new RavenJArray(GetQueryStringValues("id").Cast<object>());
		    }

			var result = new MultiLoadResult();
			var loadedIds = new HashSet<string>();
            var includedIds = new HashSet<string>();
			var includes = GetQueryStringValues("include") ?? new string[0];
			var transformer = GetQueryStringValue("transformer") ?? GetQueryStringValue("resultTransformer");
			var queryInputs = ExtractQueryInputs();
			var transactionInformation = GetRequestTransaction();
			var includedEtags = new List<byte>();

		    if (string.IsNullOrEmpty(transformer) == false)
		    {
                var transformerDef = Database.IndexDefinitionStorage.GetTransformer(transformer);
		        if (transformerDef == null)
		            return GetMessageWithObject(new {Error = "No such transformer: " + transformer}, HttpStatusCode.BadRequest);
                includedEtags.AddRange(transformerDef.GetHashCodeBytes());

		    }

			Database.TransactionalStorage.Batch(actions =>
			{
				foreach (RavenJToken item in itemsToLoad)
				{
					var value = item.Value<string>();
					if (loadedIds.Add(value) == false)
						continue;
					var documentByKey = string.IsNullOrEmpty(transformer)
										? Database.Documents.Get(value, transactionInformation)
                                        : Database.Documents.GetWithTransformer(value, transformer, transactionInformation, queryInputs, out includedIds);
				    if (documentByKey == null)
				    {
                        if(ClientIsV3OrHigher)
                            result.Results.Add(null); 
                        continue;
				    }
					result.Results.Add(documentByKey.ToJson());

					if (documentByKey.Etag != null)
						includedEtags.AddRange(documentByKey.Etag.ToByteArray());

					includedEtags.Add((documentByKey.NonAuthoritativeInformation ?? false) ? (byte)0 : (byte)1);
				}

				var addIncludesCommand = new AddIncludesCommand(Database, transactionInformation, (etag, includedDoc) =>
				{
					includedEtags.AddRange(etag.ToByteArray());
					result.Includes.Add(includedDoc);
				}, includes, loadedIds);

				foreach (var item in result.Results.Where(item => item != null))
				{
					addIncludesCommand.Execute(item);
				}
			});


			foreach (var includedId in includedIds)
		    {
		        var doc = Database.Documents.Get(includedId, transactionInformation);
		        if (doc == null)
		        {
                    continue;
		        }
                includedEtags.AddRange(doc.Etag.ToByteArray());
		        result.Includes.Add(doc.ToJson());
		    }

            var computeHash = Encryptor.Current.Hash.Compute16(includedEtags.ToArray());
            Etag computedEtag = Etag.Parse(computeHash);

			if (MatchEtag(computedEtag))
			{
				return GetEmptyMessage(HttpStatusCode.NotModified);
			}

			var msg = GetMessageWithObject(result);
			WriteETag(computedEtag, msg);

			AddRequestTraceInfo(sb => sb.Append("Results count: {0}, includes count: {1}", result.Results.Count, result.Includes.Count).AppendLine());

			return msg;
		}
        private void PerformSearch(IHttpContext context, string indexName, Index index, MoreLikeThisQueryParameters parameters)
        {
            IndexSearcher searcher;

            using (Database.IndexStorage.GetCurrentIndexSearcher(indexName, out searcher))
            {
                var documentQuery = new BooleanQuery();

                if (!string.IsNullOrEmpty(parameters.DocumentId))
                {
                    documentQuery.Add(new TermQuery(new Term(Constants.DocumentIdFieldName, parameters.DocumentId.ToLowerInvariant())),
                                      BooleanClause.Occur.MUST);
                }

                foreach (string key in parameters.MapGroupFields.Keys)
                {
                    documentQuery.Add(new TermQuery(new Term(key, parameters.MapGroupFields[key])),
                                      BooleanClause.Occur.MUST);
                }

                var td = searcher.Search(documentQuery, 1);

                // get the current Lucene docid for the given RavenDB doc ID
                if (td.ScoreDocs.Length == 0)
                {
                    context.SetStatusToNotFound();
                    context.WriteJson(new { Error = "Document " + parameters.DocumentId + " could not be found" });
                    return;
                }

                var ir  = searcher.GetIndexReader();
                var mlt = new RavenMoreLikeThis(ir);

                AssignParameters(mlt, parameters);

                if (!string.IsNullOrWhiteSpace(parameters.StopWordsDocumentId))
                {
                    var stopWordsDoc = Database.Get(parameters.StopWordsDocumentId, null);
                    if (stopWordsDoc == null)
                    {
                        context.SetStatusToNotFound();
                        context.WriteJson(
                            new
                        {
                            Error = "Stop words document " + parameters.StopWordsDocumentId + " could not be found"
                        });
                        return;
                    }
                    var stopWords = stopWordsDoc.DataAsJson.JsonDeserialization <StopWordsSetup>().StopWords;
                    mlt.SetStopWords(new Hashtable(stopWords.ToDictionary(x => x.ToLower())));
                }

                var fieldNames = parameters.Fields ?? GetFieldNames(ir);
                mlt.SetFieldNames(fieldNames);

                var toDispose = new List <Action>();
                PerFieldAnalyzerWrapper perFieldAnalyzerWrapper = null;
                try
                {
                    perFieldAnalyzerWrapper = index.CreateAnalyzer(new LowerCaseKeywordAnalyzer(), toDispose, true);
                    mlt.SetAnalyzer(perFieldAnalyzerWrapper);

                    var mltQuery = mlt.Like(td.ScoreDocs[0].doc);
                    var tsdc     = TopScoreDocCollector.create(context.GetPageSize(Database.Configuration.MaxPageSize), true);
                    searcher.Search(mltQuery, tsdc);
                    var hits          = tsdc.TopDocs().ScoreDocs;
                    var jsonDocuments = GetJsonDocuments(parameters, searcher, indexName, hits, td.ScoreDocs[0].doc);

                    var result = new MultiLoadResult();

                    var includedEtags = new List <byte>(jsonDocuments.SelectMany(x => x.Etag.Value.ToByteArray()));
                    includedEtags.AddRange(Database.GetIndexEtag(indexName, null).ToByteArray());
                    var loadedIds          = new HashSet <string>(jsonDocuments.Select(x => x.Key));
                    var addIncludesCommand = new AddIncludesCommand(Database, GetRequestTransaction(context), (etag, includedDoc) =>
                    {
                        includedEtags.AddRange(etag.ToByteArray());
                        result.Includes.Add(includedDoc);
                    }, context.Request.QueryString.GetValues("include") ?? new string[0], loadedIds);

                    foreach (var jsonDocumet in jsonDocuments)
                    {
                        result.Results.Add(jsonDocumet.ToJson());
                        addIncludesCommand.Execute(jsonDocumet.DataAsJson);
                    }

                    Guid computedEtag;
                    using (var md5 = MD5.Create())
                    {
                        var computeHash = md5.ComputeHash(includedEtags.ToArray());
                        computedEtag = new Guid(computeHash);
                    }

                    if (context.MatchEtag(computedEtag))
                    {
                        context.SetStatusToNotModified();
                        return;
                    }

                    context.Response.AddHeader("ETag", computedEtag.ToString());
                    context.WriteJson(result);
                }
                finally
                {
                    if (perFieldAnalyzerWrapper != null)
                    {
                        perFieldAnalyzerWrapper.Close();
                    }
                    foreach (var action in toDispose)
                    {
                        action();
                    }
                }
            }
        }
Example #26
0
        private void PerformSearch(IHttpContext context, string indexName, IndexDefinition indexDefinition, MoreLikeThisQueryParameters parameters)
        {
            IndexSearcher searcher;

            using (Database.IndexStorage.GetCurrentIndexSearcher(indexName, out searcher))
            {
                var td = searcher.Search(new TermQuery(new Term(Constants.DocumentIdFieldName, parameters.DocumentId)), 1);
                // get the current Lucene docid for the given RavenDB doc ID
                if (td.ScoreDocs.Length == 0)
                {
                    context.SetStatusToNotFound();
                    context.WriteJson(new { Error = "Document " + parameters.DocumentId + " could not be found" });
                    return;
                }
                var ir  = searcher.GetIndexReader();
                var mlt = new RavenMoreLikeThis(ir);

                AssignParameters(mlt, parameters);

                if (!string.IsNullOrWhiteSpace(parameters.StopWordsDocumentId))
                {
                    var stopWordsDoc = Database.Get(parameters.StopWordsDocumentId, null);
                    if (stopWordsDoc == null)
                    {
                        context.SetStatusToNotFound();
                        context.WriteJson(
                            new
                        {
                            Error = "Stop words document " + parameters.StopWordsDocumentId + " could not be found"
                        });
                        return;
                    }
                    var stopWords = stopWordsDoc.DataAsJson.JsonDeserialization <StopWordsSetup>().StopWords;
                    mlt.SetStopWords(new Hashtable(stopWords.ToDictionary(x => x.ToLower())));
                }

                var fieldNames = parameters.Fields ?? GetFieldNames(ir);
                mlt.SetFieldNames(fieldNames);

                mlt.Analyzers = GetAnalyzers(indexDefinition, fieldNames);

                var mltQuery = mlt.Like(td.ScoreDocs[0].doc);
                var tsdc     = TopScoreDocCollector.create(context.GetPageSize(Database.Configuration.MaxPageSize), true);
                searcher.Search(mltQuery, tsdc);
                var hits        = tsdc.TopDocs().ScoreDocs;
                var documentIds = hits.Select(hit => searcher.Doc(hit.doc).Get(Constants.DocumentIdFieldName)).Distinct();

                var jsonDocuments =
                    documentIds
                    .Where(docId => string.Equals(docId, parameters.DocumentId, StringComparison.InvariantCultureIgnoreCase) == false)
                    .Select(docId => Database.Get(docId, null))
                    .Where(it => it != null)
                    .ToArray();

                var result = new MultiLoadResult();

                var includedEtags = new List <byte>(jsonDocuments.SelectMany(x => x.Etag.Value.ToByteArray()));
                includedEtags.AddRange(Database.GetIndexEtag(indexName, null).ToByteArray());
                var loadedIds          = new HashSet <string>(jsonDocuments.Select(x => x.Key));
                var addIncludesCommand = new AddIncludesCommand(Database, GetRequestTransaction(context), (etag, includedDoc) =>
                {
                    includedEtags.AddRange(etag.ToByteArray());
                    result.Includes.Add(includedDoc);
                }, context.Request.QueryString.GetValues("include") ?? new string[0], loadedIds);

                foreach (var jsonDocumet in jsonDocuments)
                {
                    result.Results.Add(jsonDocumet.ToJson());
                    addIncludesCommand.Execute(jsonDocumet.DataAsJson);
                }

                Guid computedEtag;
                using (var md5 = MD5.Create())
                {
                    var computeHash = md5.ComputeHash(includedEtags.ToArray());
                    computedEtag = new Guid(computeHash);
                }

                if (context.MatchEtag(computedEtag))
                {
                    context.SetStatusToNotModified();
                    return;
                }

                context.Response.AddHeader("ETag", computedEtag.ToString());
                context.WriteJson(result);
            }
        }
Example #27
0
        public override void Respond(IHttpContext context)
        {
            RavenJArray itemsToLoad;

            if (context.Request.HttpMethod == "POST")
            {
                itemsToLoad = context.ReadJsonArray();
            }
            else
            {
                itemsToLoad = new RavenJArray(context.Request.QueryString.GetValues("id"));
            }
            var result      = new MultiLoadResult();
            var loadedIds   = new HashSet <string>();
            var includes    = context.Request.QueryString.GetValues("include") ?? new string[0];
            var transformer = context.Request.QueryString["transformer"] ?? context.Request.QueryString["resultTransformer"];

            var queryInputs = context.ExtractQueryInputs();

            var transactionInformation = GetRequestTransaction(context);
            var includedEtags          = new List <byte>();

            Database.TransactionalStorage.Batch(actions =>
            {
                foreach (RavenJToken item in itemsToLoad)
                {
                    var value = item.Value <string>();
                    if (loadedIds.Add(value) == false)
                    {
                        continue;
                    }
                    JsonDocument documentByKey = string.IsNullOrEmpty(transformer)
                                                        ? Database.Get(value, transactionInformation)
                                        : Database.GetWithTransformer(value, transformer, transactionInformation, queryInputs);
                    if (documentByKey == null)
                    {
                        continue;
                    }
                    result.Results.Add(documentByKey.ToJson());

                    if (documentByKey.Etag != null)
                    {
                        includedEtags.AddRange(documentByKey.Etag.ToByteArray());
                    }
                    includedEtags.Add((documentByKey.NonAuthoritativeInformation ?? false) ? (byte)0 : (byte)1);
                }

                var addIncludesCommand = new AddIncludesCommand(Database, transactionInformation, (etag, includedDoc) =>
                {
                    includedEtags.AddRange(etag.ToByteArray());
                    result.Includes.Add(includedDoc);
                }, includes, loadedIds);

                foreach (var item in result.Results.Where(item => item != null))
                {
                    addIncludesCommand.Execute(item);
                }
            });

            Etag computedEtag;

            using (var md5 = MD5.Create())
            {
                var computeHash = md5.ComputeHash(includedEtags.ToArray());
                computedEtag = Etag.Parse(computeHash);
            }

            if (context.MatchEtag(computedEtag))
            {
                context.SetStatusToNotModified();
                return;
            }

            context.WriteETag(computedEtag);
            context.WriteJson(result);
        }
        public MoreLikeThisQueryResult ExecuteMoreLikeThisQuery(MoreLikeThisQuery query, TransactionInformation transactionInformation, int pageSize = 25, string[] include = null)
        {
            if (query == null)
            {
                throw new ArgumentNullException("query");
            }

            var index = database.IndexStorage.GetIndexInstance(query.IndexName);

            if (index == null)
            {
                throw new InvalidOperationException("The index " + query.IndexName + " cannot be found");
            }

            if (string.IsNullOrEmpty(query.DocumentId) && query.MapGroupFields.Count == 0)
            {
                throw new InvalidOperationException("The document id or map group fields are mandatory");
            }

            IndexSearcher searcher;

            using (database.IndexStorage.GetCurrentIndexSearcher(query.IndexName, out searcher))
            {
                var documentQuery = new BooleanQuery();

                if (string.IsNullOrEmpty(query.DocumentId) == false)
                {
                    documentQuery.Add(new TermQuery(new Term(Constants.DocumentIdFieldName, query.DocumentId.ToLowerInvariant())), Occur.MUST);
                }

                foreach (string key in query.MapGroupFields.Keys)
                {
                    documentQuery.Add(new TermQuery(new Term(key, query.MapGroupFields[key])), Occur.MUST);
                }

                var td = searcher.Search(documentQuery, 1);

                // get the current Lucene docid for the given RavenDB doc ID
                if (td.ScoreDocs.Length == 0)
                {
                    throw new InvalidOperationException("Document " + query.DocumentId + " could not be found");
                }

                var ir  = searcher.IndexReader;
                var mlt = new RavenMoreLikeThis(ir);

                AssignParameters(mlt, query);

                if (string.IsNullOrWhiteSpace(query.StopWordsDocumentId) == false)
                {
                    var stopWordsDoc = database.Get(query.StopWordsDocumentId, null);
                    if (stopWordsDoc == null)
                    {
                        throw new InvalidOperationException("Stop words document " + query.StopWordsDocumentId + " could not be found");
                    }

                    var stopWordsSetup = stopWordsDoc.DataAsJson.JsonDeserialization <StopWordsSetup>();
                    if (stopWordsSetup.StopWords != null)
                    {
                        var stopWords = stopWordsSetup.StopWords;
                        var ht        = new Hashtable(StringComparer.InvariantCultureIgnoreCase);
                        foreach (var stopWord in stopWords)
                        {
                            ht[stopWord] = stopWord;
                        }
                        mlt.SetStopWords(ht);
                    }
                }

                var fieldNames = query.Fields ?? GetFieldNames(ir);
                mlt.SetFieldNames(fieldNames);

                var toDispose = new List <Action>();
                RavenPerFieldAnalyzerWrapper perFieldAnalyzerWrapper = null;
                try
                {
                    perFieldAnalyzerWrapper = index.CreateAnalyzer(new LowerCaseKeywordAnalyzer(), toDispose, true);
                    mlt.SetAnalyzer(perFieldAnalyzerWrapper);

                    var mltQuery = mlt.Like(td.ScoreDocs[0].Doc);
                    var tsdc     = TopScoreDocCollector.Create(pageSize, true);
                    searcher.Search(mltQuery, tsdc);
                    var hits          = tsdc.TopDocs().ScoreDocs;
                    var jsonDocuments = GetJsonDocuments(query, searcher, index, query.IndexName, hits, td.ScoreDocs[0].Doc);

                    var result = new MultiLoadResult();

                    var includedEtags = new List <byte>(jsonDocuments.SelectMany(x => x.Etag.Value.ToByteArray()));
                    includedEtags.AddRange(database.GetIndexEtag(query.IndexName, null).ToByteArray());
                    var loadedIds          = new HashSet <string>(jsonDocuments.Select(x => x.Key));
                    var addIncludesCommand = new AddIncludesCommand(database, transactionInformation, (etag, includedDoc) =>
                    {
                        includedEtags.AddRange(etag.ToByteArray());
                        result.Includes.Add(includedDoc);
                    }, include ?? new string[0], loadedIds);

                    foreach (var jsonDocument in jsonDocuments)
                    {
                        result.Results.Add(jsonDocument.ToJson());
                        addIncludesCommand.Execute(jsonDocument.DataAsJson);
                    }

                    Guid computedEtag;
                    using (var md5 = MD5.Create())
                    {
                        var computeHash = md5.ComputeHash(includedEtags.ToArray());
                        computedEtag = new Guid(computeHash);
                    }

                    return(new MoreLikeThisQueryResult
                    {
                        Etag = computedEtag,
                        Result = result,
                    });
                }
                finally
                {
                    if (perFieldAnalyzerWrapper != null)
                    {
                        perFieldAnalyzerWrapper.Close();
                    }
                    foreach (var action in toDispose)
                    {
                        action();
                    }
                }
            }
        }
		public MoreLikeThisQueryResult ExecuteMoreLikeThisQuery(MoreLikeThisQuery query, TransactionInformation transactionInformation, int pageSize = 25, string[] include = null)
		{
			if (query == null) throw new ArgumentNullException("query");

			var index = database.IndexStorage.GetIndexInstance(query.IndexName);
			if (index == null)
				throw new InvalidOperationException("The index " + query.IndexName + " cannot be found");

			if (string.IsNullOrEmpty(query.DocumentId) && query.MapGroupFields.Count == 0)
				throw new InvalidOperationException("The document id or map group fields are mandatory");

			IndexSearcher searcher;
			using (database.IndexStorage.GetCurrentIndexSearcher(index.indexId, out searcher))
			{
				var documentQuery = new BooleanQuery();

				if (string.IsNullOrEmpty(query.DocumentId) == false)
				{
					documentQuery.Add(new TermQuery(new Term(Constants.DocumentIdFieldName, query.DocumentId.ToLowerInvariant())), Occur.MUST);
				}

				foreach (string key in query.MapGroupFields.Keys)
				{
					documentQuery.Add(new TermQuery(new Term(key, query.MapGroupFields[key])), Occur.MUST);
				}

				var td = searcher.Search(documentQuery, 1);

				// get the current Lucene docid for the given RavenDB doc ID
				if (td.ScoreDocs.Length == 0)
					throw new InvalidOperationException("Document " + query.DocumentId + " could not be found");

				var ir = searcher.IndexReader;
				var mlt = new RavenMoreLikeThis(ir);

				AssignParameters(mlt, query);

				if (string.IsNullOrWhiteSpace(query.StopWordsDocumentId) == false)
				{
					var stopWordsDoc = database.Documents.Get(query.StopWordsDocumentId, null);
					if (stopWordsDoc == null)
						throw new InvalidOperationException("Stop words document " + query.StopWordsDocumentId + " could not be found");

					var stopWordsSetup = stopWordsDoc.DataAsJson.JsonDeserialization<StopWordsSetup>();
					if (stopWordsSetup.StopWords != null)
					{
						var stopWords = stopWordsSetup.StopWords;
						var ht = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
						foreach (var stopWord in stopWords)
						{
							ht.Add(stopWord);
						}
						mlt.SetStopWords(ht);
					}
				}

				var fieldNames = query.Fields ?? GetFieldNames(ir);
				mlt.SetFieldNames(fieldNames);

				var toDispose = new List<Action>();
				RavenPerFieldAnalyzerWrapper perFieldAnalyzerWrapper = null;
				try
				{
					perFieldAnalyzerWrapper = index.CreateAnalyzer(new LowerCaseKeywordAnalyzer(), toDispose, true);
					mlt.Analyzer = perFieldAnalyzerWrapper;

					var mltQuery = mlt.Like(td.ScoreDocs[0].Doc);
					var tsdc = TopScoreDocCollector.Create(pageSize, true);
					searcher.Search(mltQuery, tsdc);
					var hits = tsdc.TopDocs().ScoreDocs;
					var jsonDocuments = GetJsonDocuments(query, searcher, index, query.IndexName, hits, td.ScoreDocs[0].Doc);

					var result = new MultiLoadResult();

					var includedEtags = new List<byte>(jsonDocuments.SelectMany(x => x.Etag.ToByteArray()));
					includedEtags.AddRange(database.Indexes.GetIndexEtag(query.IndexName, null).ToByteArray());
					var loadedIds = new HashSet<string>(jsonDocuments.Select(x => x.Key));
					var addIncludesCommand = new AddIncludesCommand(database, transactionInformation, (etag, includedDoc) =>
					{
						includedEtags.AddRange(etag.ToByteArray());
						result.Includes.Add(includedDoc);
					}, include ?? new string[0], loadedIds);

					foreach (var jsonDocument in jsonDocuments)
					{
						result.Results.Add(jsonDocument.ToJson());
						addIncludesCommand.Execute(jsonDocument.DataAsJson);
					}

					Etag computedEtag;
					using (var md5 = MD5.Create())
					{
						var computeHash = md5.ComputeHash(includedEtags.ToArray());
						computedEtag = Etag.Parse(computeHash);
					}

					return new MoreLikeThisQueryResult
					{
						Etag = computedEtag,
						Result = result,
					};
				}
				finally
				{
					if (perFieldAnalyzerWrapper != null)
						perFieldAnalyzerWrapper.Close();
					foreach (var action in toDispose)
					{
						action();
					}
				}
			}
		}