C# 为什么不是';我的索引中的Sum()是否有效?

C# 为什么不是';我的索引中的Sum()是否有效?,c#,ravendb,C#,Ravendb,我有以下测试: public class ListingEventTest { public ListingEventTest() { Artists = new List<ArtistTest>(); } public List<ArtistTest> Artists { get; set; } public string Id { get; set; } public string Name { get;

我有以下测试:

public class ListingEventTest
{
    public ListingEventTest()
    {
        Artists = new List<ArtistTest>();
    }
    public List<ArtistTest> Artists { get; set; }
    public string Id { get; set; }
    public string Name { get; set; }
    public double Popularity { get; set; }
}

public class ArtistTest
{
    public string Id { get; set; }
    public Stat Stats { get; set; }
}

public class Stat
{
    public double Popularity { get; set; }
}


public class ArtistsWithStats_ByName : AbstractIndexCreationTask<ListingEventTest>
{
    public ArtistsWithStats_ByName()
    {
        Map = listingEvents => from listingEvent in listingEvents
                               let artists = LoadDocument<ArtistTest>(listingEvent.Artists.Select(x => x.Id))
                               select new
                               {
                                   Popularity = artists.Average(x => x.Stats.Popularity),
                                   listingEvent.Name
                               };
    }
}



[TestFixture]
public class IndexCanDoSums
{
    [Test]
    public async void WhenListingEventArtistsHaveStatsIndexReturnsPopularity()
    {
        var store = new EmbeddableDocumentStore
        {
            UseEmbeddedHttpServer = true,
            Configuration =
            {
                RunInUnreliableYetFastModeThatIsNotSuitableForProduction = true,
                RunInMemory = true,

            }
        }.Initialize();

        IndexCreation.CreateIndexes(typeof(ArtistsWithStats_ByName).Assembly, store);

        using (var session = store.OpenAsyncSession())
        {
            for (int i = 0; i < 10; i++)
            {
                var le = new ListingEventTest
                {
                    Name = "test-" + i
                };

                await session.StoreAsync(le);

                for (int j = 0; j < 2; j++)
                {
                    var artist = new ArtistTest
                    {
                        Stats = new Stat
                        {
                            Popularity = 0.89d
                        }
                    };

                    await session.StoreAsync(artist);

                    le.Artists.Add(artist);
                }

                await session.SaveChangesAsync();
            }
        }

        Thread.Sleep(2000);

        using (var session = store.OpenAsyncSession())
        {
             var query = session
            .Advanced.AsyncLuceneQuery<ListingEventTest>("ArtistsWithStats/ByName");

            var result = await query.ToListAsync();

            result.First().Popularity.Should().NotBe(0);
        }
    }
}
公共类ListingEventTest
{
public ListingEventTest()
{
艺术家=新列表();
}
公开列表艺术家{get;set;}
公共字符串Id{get;set;}
公共字符串名称{get;set;}
公共双流行{get;set;}
}
公开课艺员测验
{
公共字符串Id{get;set;}
公共统计数据{get;set;}
}
公共类统计
{
公共双流行{get;set;}
}
公共类ArtistsWithStats_ByName:AbstractIndexCreationTask
{
公共艺人(按姓名)
{
Map=listingEvents=>来自listingEvents中的listingEvent
让艺术家=加载文档(listingEvent.artists.Select(x=>x.Id))
选择新的
{
人气=艺术家。平均(x=>x.Stats.Popularity),
listingEvent.Name
};
}
}
[测试夹具]
公共类索引
{
[测试]
当存在VenStartListShaveStatintIndexReturnsPopularity()时,公共异步无效
{
变量存储=新的EmbeddedBleDocumentStore
{
UseEmbeddedHttpServer=true,
配置=
{
RuninUnreliableyeTFastMode不适用于生产=真,
RunInMemory=true,
}
}.Initialize();
CreateIndexes(typeof(ArtistsWithStats_ByName).Assembly,store);
使用(var session=store.OpenAsyncSession())
{
对于(int i=0;i<10;i++)
{
var le=新的ListingEventTest
{
Name=“测试-”+i
};
等待会话。StoreAsync(le);
对于(int j=0;j<2;j++)
{
var artist=新艺人测试
{
统计数据=新统计数据
{
流行度=0.89d
}
};
等待会话。StoreAsync(艺术家);
乐。艺术家。添加(艺术家);
}
wait session.saveChangesSync();
}
}
《睡眠》(2000年);
使用(var session=store.OpenAsyncSession())
{
var query=会话
.Advanced.AsyncLuceneQuery(“ArtistsWithStats/ByName”);
var result=wait query.ToListAsync();
result.First().Popularity.Should().NotBe(0);
}
}
}
当我查询此索引时,
Popularity
始终为0


有什么想法吗?

这里发生了一些有趣的事情

首先,您将ArtistTest存储在ListingEventTest文档下,而不是作为单独的文档,因此在索引中不需要调用LoadDocument,您可以执行以下操作:

from listingEvent in listingEvents
from artist in listingEvent.Artists
select ...
其次,仅映射索引非常类似于SQL索引,您只需调出要查询的列。在这里,您正在对一组隐藏的属性进行计算,并且您有一个顶级属性,您希望在其中存储该信息,但最终的结果是,您计算的属性值进入了Lucene索引(因此,如果您愿意,您可以按受欢迎程度进行查询)但是返回的数据直接来自未更改的文档。映射定义了进入Lucene的内容,Lucene指向文档id,然后文档存储将文档作为结果返回

这可以通过在索引的构造函数中调用
Store(x=>x.Popularity)
进行修改,该构造函数将存储稍后调用的值,但老实说,我不确定您的计算值或文档的值(为零)是否会赢

考虑到这一点,仅仅为了在索引过程中填充文档属性就变得非常混乱,这就是为什么使用一个表示映射状态的类通常是更好的选择,然后实现
AbstractIndexCreationTask
,其中
TReduceResult
类将只包含映射的结果,即
Name
Popularity


然后,当您从中查询时,可以使用
.ProjectFromIndexFieldsInto()
从存储的索引结果而不是从文档存储中获取结果。

给出一个小而完整的示例,演示我们可以实际尝试的问题。但这应该可以正常工作吗?不,您键入的代码甚至无法编译,因为
.Name
后面没有逗号。说它应该做什么或不应该做什么是一个道德问题;你声称它确实做了一件特殊的事情;证明索赔是正确的是理解索赔的第一步。这可能是因为你输入了更多的错误,这些错误解释了意外的结果。可能是这位艺术家的统计数据总和为零。我会设置一个失败的test@EricLippert用失败的测试更新了q抱歉-它应该是非规范化的引用但这看起来很正确-感谢您花时间:)嗯-我不能在lucenequery上使用ProjectFromIndexFieldsInto