RavenDB ID gets corrupted code created by index

Firstly, I am just starting with RavenDB, so please be patient when I explain the problem. I am trying to create my first map, map, reduce, convert index. Yes, I know that I am trying to do a lot, but I have most of the work.

So, first I do this in my global.asax to make sure that all the “ID” properties are used as the document identifier.

_documentStore.Conventions.FindIdentityProperty = p => p.Name == "ID"; 

Now let's look at the index.

 public class ProblemListViewIndex : AbstractMultiMapIndexCreationTask<ProblemListView> { public ProblemListViewIndex() { AddMap<Problem>(problems => from problem in problems select new { ID = problem.ID, SolutionCount = 0, }); AddMap<Solution>(solutions => from solution in solutions select new { ID = solution.ProblemID, SolutionCount = 1, }); Reduce = results => from result in results group result by result.ID into g select new { ID = g.Key, SolutionCount = g.Sum(x => x.SolutionCount), }; Indexes.Add(x => x.ID, FieldIndexing.Analyzed); TransformResults = (database, results) => from result in results let problem = database.Load<Problem>("problems/" + result.ID.ToString()) let user = database.Load<User>("users/" + problem.PostedByID.ToString()) select new { ID = result.ID, PostedByID = problem.PostedByID, PostedByName = user.DisplayName, SolutionCount = result.SolutionCount, }; } } 

So, everything looks good, and when I test the index on the RavenDB website, I get mixed results. I have recurring forecasts. I have two forecasts that I expect, but two copies of them. This is what the “ID” looks like on the projection results.

  • problems / 194
  • problems / 195
  • 194
  • 195

I am confused, but then I returned and looked at the "cards". My code has been translated to something else in the generated index. Here's what the first map looks like when you create it first.

 docs.Problems .Select(problem => new {ID = problem.__document_id, SolutionCount = 0}) 

Even being new to RavenDB, I see a problem. It uses the __document_id field when I want to use the ID field. I modify the map and then save the index as follows.

 docs.Problems .Select(problem => new {ID = problem.ID, SolutionCount = 0}) 

As soon as I do this, my forecast looks exactly as I expected, and how I want it.

  • 194
  • 195

My question is, what do I need to do in my code to create my index using "ID" over "__document_id"?

+4
source share
3 answers

I do not understand what is wrong here. I # compiled a test using your code and get what I expected:

 public class MultiMapWithTransformAndCustomId { public class Problem { public string ID { get; set; } public string PostedByID { get; set; } public string Foo { get; set; } } public class Solution { public string ID { get; set; } public string ProblemID { get; set; } public string Foo { get; set; } } public class User { public string ID { get; set; } public string DisplayName { get; set; } } public class ProblemListViewIndex : AbstractMultiMapIndexCreationTask<ProblemListViewIndex.ReduceResult> { public class ReduceResult { public string ID { get; set; } public int SolutionCount { get; set; } public string PostedByID { get; set; } public string PostedByName { get; set; } } public ProblemListViewIndex() { AddMap<Problem>(problems => from problem in problems select new { ID = problem.ID, SolutionCount = 0, }); AddMap<Solution>(solutions => from solution in solutions select new { ID = solution.ProblemID, SolutionCount = 1, }); Reduce = results => from result in results group result by result.ID into g select new { ID = g.Key, SolutionCount = g.Sum(x => x.SolutionCount), }; Indexes.Add(x => x.ID, FieldIndexing.Analyzed); TransformResults = (database, results) => from result in results let problem = database.Load<Problem>(result.ID.ToString()) let user = database.Load<User>(problem.PostedByID.ToString()) select new { ID = result.ID, PostedByID = problem.PostedByID, PostedByName = user.DisplayName, SolutionCount = result.SolutionCount, }; } } [Fact] public void Can_do_simple_query() { using (var documentStore = new EmbeddableDocumentStore { RunInMemory = true }) { documentStore.Conventions.FindIdentityProperty = p => p.Name == "ID"; documentStore.Initialize(); using (var documentSession = documentStore.OpenSession()) { documentSession.Store(new User {ID = "users/1", DisplayName = "Daniel"}); documentSession.Store(new User {ID = "users/2", DisplayName = "Lang"}); documentSession.Store(new Problem {ID = "problems/194", PostedByID = "users/1"}); documentSession.Store(new Problem {ID = "problems/195", PostedByID = "users/2"}); documentSession.Store(new Solution {ID = "solutions/1", ProblemID = "problems/194"}); documentSession.Store(new Solution {ID = "solutions/2", ProblemID = "problems/194"}); documentSession.Store(new Solution {ID = "solutions/3", ProblemID = "problems/195"}); documentSession.SaveChanges(); } new ProblemListViewIndex().Execute(documentStore); using (var documentSession = documentStore.OpenSession()) { var results = documentSession.Query<ProblemListViewIndex.ReduceResult, ProblemListViewIndex>() .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite()) .ToList(); Assert.Equal(2, results.Count); var daniel = results.First(x => x.PostedByName == "Daniel"); var lang = results.First(x => x.PostedByName == "Lang"); Assert.Equal("problems/194", daniel.ID); Assert.Equal("problems/195", lang.ID); } } } } 
0
source

I found this problem too, I found work by adding another field to my index, for example SolutionId, and set its value to the same as Id.

Then you can run queries against this value without any problems.

I asked the same question here before, and apparently this is by design.

0
source

Adding to what Daniel said is solution.ProblemID is a whole field.

The simplest solution is to change the display of the solution:

  ID = "problems/" + solution.ProblemID, 

But I would say that you will use string links instead of whole links, this will make things easier.

0
source

Source: https://habr.com/ru/post/1401295/


All Articles