Идентификатор RavenDB запутался в индексе созданного кода - PullRequest
4 голосов
/ 14 марта 2012

Прежде всего, я только начинаю работать с RavenDB, поэтому, пожалуйста, будьте терпеливы, когда я объясню проблему. Я пытаюсь создать свою первую карту, карту, уменьшить, преобразовать индекс. Да, я знаю, что пытаюсь сделать много, но у меня большая часть работает.

Итак, сначала я делаю это в моем global.asax, чтобы убедиться, что все свойства "ID" используются в качестве идентификатора в документах.

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

ОК, теперь давайте посмотрим на индекс.

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,
                                                  };

    }
}

Так что все выглядит хорошо, и когда я тестирую индекс на веб-сайте RavenDB, я получаю смешанные результаты. У меня есть двойные прогнозы. У меня есть два прогноза, которые я ожидаю, но две их копии. Вот как выглядит «ID» на результатах проецирования.

  • проблемы / 194
  • проблемы / 195
  • 194
  • 195

Я запутался, но потом я вернулся и посмотрел на "карты". Мой код переведен на что-то другое в созданном индексе. Вот как выглядит первая карта при ее создании.

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

Даже будучи новичком в RavenDB, я вижу проблему. Он использует поле «__document_id», когда я хочу использовать поле «ID». Я изменяю карту, а затем сохраняю индекс в следующем.

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

Как только я это сделаю, моя проекция будет выглядеть именно так, как я ожидал и как я хочу.

  • 194
  • 195

Мой вопрос заключается в том, что мне нужно сделать в моем коде, чтобы индекс создавался с использованием "ID" вместо "__document_id"?

Ответы [ 3 ]

0 голосов
/ 14 марта 2012

Я не вижу, что здесь не так.Я # собрал тест с использованием вашего кода и получил то, что ожидал:

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 голосов
/ 14 марта 2012

В дополнение к тому, что сказал Дэниел, solution.ProblemID - это целочисленное поле.

Самое простое решение - изменить карту решения на:

    ID = "problems/" + solution.ProblemID,

Но я бы настоятельно рекомендовал вам использовать строковые ссылки вместо целочисленных ссылок, это все упростит.

0 голосов
/ 14 марта 2012

Я также нашел эту проблему, я нашел способ обойти, добавив еще одно поле в свой индекс, например SolutionId, и установив его значение равным Id.

После этого вы сможете запуститьзапросы к этому значению без каких-либо проблем.

Я задавал тот же вопрос здесь и раньше, и, видимо, это намеренно.

...