【问题标题】:RavenDB Index no longer returning resultsRavenDB 索引不再返回结果
【发布时间】:2012-01-30 16:03:04
【问题描述】:

我正在尝试将来自 here 的 Ayende 订单搜索应用到现有索引。

当前索引如下所示:

public class HomeBlurb_IncludeTotalCosts_Search2 : AbstractIndexCreationTask<MPDocument, HomeBlurb_IncludeTotalCosts_Search2.ReduceResult>
{
    public class ReduceResult
    {
        public string Name { get; set; }
        public string Constituency { get; set; }
        public decimal? AmountPaid { get; set; }
    }

    public HomeBlurb_IncludeTotalCosts_Search2()
    {
        Map = mps => from mp in mps
                        from exp in mp.Expenses
                        select new
                        {
                            mp.Name,
                            mp.Constituency,
                            exp.AmountPaid
                        };

        Reduce = results => from result in results
                            group result by new { result.Name, result.Constituency } into g
                            select new
                            {
                                Name = g.Key.Name,
                                Constituency = g.Key.Constituency,
                                AmountPaid = g.Sum(x => x.AmountPaid)
                            };

        Index(x => x.Name, FieldIndexing.Analyzed);
        Index(x => x.Constituency, FieldIndexing.Analyzed);
    }
}

这个索引工作正常。但是,当我尝试将地图更改为:

from mp in mps
from exp in mp.Expenses
select new
{
    Query = new object[]{mp.Name,mp.Constituency},
    mp.Name,
    mp.Constituency,
    exp.AmountPaid
};

和归约到

from result in results
group result by new { result.Name, result.Constituency } into g
select new
{
    Query = "",
    Name = g.Key.Name,
    Constituency = g.Key.Constituency,
    AmountPaid = g.Sum(x => x.AmountPaid)
};

然后,我在查询 Query 属性时没有得到任何结果。如果我删除 reduce 索引返回数据,但它总是返回完整的MPDocument,这比我要实现的要多得多。有没有办法使用原始帖子中描述的技术,也利用了减少?

【问题讨论】:

  • 在您的 Reduce 语句中,您将 Query 设置为空字符串,这是正确的吗?如果是这样,唯一匹配它的查询是一个空字符串!
  • 当你有一个带有 Reduce 部分的索引时,你查询的是 Reduce 部分的输出,而不是 Map 部分

标签: ravendb


【解决方案1】:

你可以在你的 reduce 函数中使用它:

Query = g.Select(x => x.Query).Where(x => x != null).FirstOrDefault()

为了查询该字段,您需要有一个单独的查询模型和一个结果模型。这是使用您的代码的完整示例:

public class MultiTermFieldInMapReduce
{
    public class MPDocument
    {
        public List<Epense> Expenses { get; set; }
        public string Name { get; set; }
        public string Constituency { get; set; }

        public class Epense
        {
            public decimal? AmountPaid { get; set; }
        }
    }

    public class HomeBlurb_IncludeTotalCosts_Search2 : AbstractIndexCreationTask<MPDocument, HomeBlurb_IncludeTotalCosts_Search2.ReduceResult>
    {
        public class ReduceResult
        {
            public string Name { get; set; }
            public string Constituency { get; set; }
            public decimal? AmountPaid { get; set; }
            public object[] Query { get; set; }
        }

        public class SearchModel
        {
            public string Name { get; set; }
            public string Constituency { get; set; }
            public decimal? AmountPaid { get; set; }
            public string Query { get; set; }
        }

        public HomeBlurb_IncludeTotalCosts_Search2()
        {
            Map = mps => from mp in mps
                         from exp in mp.Expenses
                         select new
                         {
                             mp.Name,
                             mp.Constituency,
                             exp.AmountPaid,
                             Query = new object[]
                             {
                                 mp.Name,
                                 mp.Constituency
                             }
                         };

            Reduce = results => from result in results
                                group result by new { result.Name, result.Constituency } into g
                                select new
                                {
                                    Name = g.Key.Name,
                                    Constituency = g.Key.Constituency,
                                    AmountPaid = g.Sum(x => x.AmountPaid),
                                    Query = g.Select(x => x.Query).Where(x => x != null).FirstOrDefault()
                                };

            Index(x => x.Name, FieldIndexing.Analyzed);
            Index(x => x.Constituency, FieldIndexing.Analyzed);
        }
    }

    [Fact]
    public void Query_returns_results()
    {
        using (var store = new EmbeddableDocumentStore { RunInMemory = true }.Initialize())
        {
            using (var session = store.OpenSession())
            {
                session.Store(new MapReduceError.MPDocument
                {
                    Name = "test1",
                    Expenses = new List<MapReduceError.MPDocument.Epense>
                    {
                        new MapReduceError.MPDocument.Epense {AmountPaid = 5.5m},
                        new MapReduceError.MPDocument.Epense {AmountPaid = 5.5m},
                        new MapReduceError.MPDocument.Epense {AmountPaid = 5.5m},
                        new MapReduceError.MPDocument.Epense {AmountPaid = 5.5m}
                    }
                });

                session.Store(new MapReduceError.MPDocument
                {
                    Name = "test2",
                    Expenses = new List<MapReduceError.MPDocument.Epense>
                    {
                        new MapReduceError.MPDocument.Epense {AmountPaid = 10},
                        new MapReduceError.MPDocument.Epense {AmountPaid = 10},
                        new MapReduceError.MPDocument.Epense {AmountPaid = 10},
                        new MapReduceError.MPDocument.Epense {AmountPaid = 10}
                    }
                });

                session.SaveChanges();
            }

            new HomeBlurb_IncludeTotalCosts_Search2().Execute(store);

            using (var session = store.OpenSession())
            {
                var results =
                    session.Query
                        <HomeBlurb_IncludeTotalCosts_Search2.SearchModel, HomeBlurb_IncludeTotalCosts_Search2>()
                        .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
                        .Where(x => x.Query == "test1")
                        .As<HomeBlurb_IncludeTotalCosts_Search2.ReduceResult>()
                        .ToList();

                Assert.Equal(1, results.Count);
                Assert.Equal(22, results.First().AmountPaid);
            }
        }

    }
}

【讨论】:

    【解决方案2】:

    我认为您不需要 Map/Reduce 索引来执行此操作,您似乎只是在减少 MPDocument 名称和选区,我猜这是每个 MP 所独有的。

    我认为你想使用 TransformResults,这样你就可以改变输出的形状,就像这样:

     TransformResults =
                (database, mps) => from mp in mps
                                     select new 
                                     {
                                         mp.Name,
                                         mp.???
                                         < JUST THE BITS YOU WANT RETURNED >
                                     };
    

    然后你像这样查询:

    session.Query<mp>("index name")
            .Where(..)
            .As<MPQueryResult>()
            .ToList()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多