RavenDB ID在代码创建的索引中搞砸了

时间:2012-03-14 03:11:29

标签: ravendb indexing

首先我刚刚开始使用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的新手我也看到了问题。当我想使用“ID”字段时,它正在使用“__document_id”字段。我更改了地图,然后将索引保存到以下内容。

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

一旦我这样做,我的投影看起来就像我预期的那样,并且我想要它。

  • 194
  • 195

我的问题是我需要在我的代码中做些什么才能使用“ID”覆盖“__document_id”创建我的索引?

3 个答案:

答案 0 :(得分:0)

我也发现了这个问题,我通过向我的索引添加另一个字段(例如SolutionId)找到了解决办法,并将其值设置为与Id相同。

然后,您应该可以针对此值运行查询而不会出现任何问题。

我之前在这里问过同样的问题,显然这是设计上的。

答案 1 :(得分:0)

我不明白这里有什么问题。我使用你的代码编写了一个测试,我得到了我的预期:

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

答案 2 :(得分:0)

除了Daniel所说的,solution.ProblemID是一个整数字段。

最简单的解决方案是将解决方案图更改为:

    ID = "problems/" + solution.ProblemID,

但我强烈建议您使用字符串引用,而不是整数引用,它会使一切变得更简单。