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>(); }
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); }
/// <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); }
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 } }
private void HandleResponse(MultiLoadResult multiLoadResult) { RequiresRetry = multiLoadOperation.SetResult(multiLoadResult); if (RequiresRetry == false) { Result = multiLoadOperation.Complete <T>(); } }
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); }
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; }
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); }
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 } }
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]; } }
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); }
/// <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); }
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 } }
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 } }
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); }
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(); } } } }
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); } }
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(); } } } }