map - 在 RavenDB Map/Reduces 中处理可为空字段的正确方法?

标签 map mapreduce ravendb nullable reduce

我应该如何映射具有可为空字段的对象?我想我必须将可为 null 的字段转换为不可为 null 的版本,而这正是我偶然发现的步骤。

映射可为 null 的属性的正确方法是什么?

public class Visit {
    public string Id { get; set; }
    public int? MediaSourceId { get; set; }
}

public class MapReduceResult
{
    public string VisitId { get; set; }
    public int MediaSourceId { get; set; }
    public string Version { get; set; }
    public int Count { get; set; }
}

AddMap<Visit>(
    visits =>
    from visit in visits
    select new
        {
            VisitId = visit.Id,
            MediaSourceId =
                (visit.MediaSourceId.HasValue)
                ? visit.MediaSourceId
                : UNUSED_MEDIASOURCE_ID,
            Version = (string) null,
            Count = 1
        });

这行不通!实际上;此 Map 被完全忽略,而其他 Map 工作正常,并且最终按预期减少。

谢谢你帮助我!

下面是一个新添加的测试用例,它因“无法将 分配给匿名类型属性”而失败。我应该如何以最少的痛苦飞行?

[TestFixture]
public class MyIndexTest
{
    private IDocumentStore _documentStore;

    [SetUp]
    public void SetUp()
    {
        _documentStore = new EmbeddableDocumentStore {RunInMemory = true}.Initialize();
        _documentStore.DatabaseCommands.DisableAllCaching();

        IndexCreation.CreateIndexes(typeof (MyIndex).Assembly, _documentStore);
    }

    [TearDown]
    public void TearDown()
    {
        _documentStore.Dispose();
    }

    [Test]
    public void ShouldWork()
    {
        InitData();

        IList<MyIndex.MapReduceResult> mapReduceResults = null;
        using (var session = _documentStore.OpenSession())
        {
            mapReduceResults =
                session.Query<MyIndex.MapReduceResult>(
                    MyIndex.INDEX_NAME)
                    .Customize(x => x.WaitForNonStaleResults()).ToArray();
        }
        Assert.That(mapReduceResults.Count, Is.EqualTo(1));
    }

    private void InitData()
    {
        var visitOne = new Visit
                           {
                               Id = "visits/64",
                               MetaData = new MetaData {CreatedDate = new DateTime(1975, 8, 6, 0, 14, 0)},
                               MediaSourceId = 1,
                           };
        var visitPageVersionOne = new VisitPageVersion
                                      {
                                          Id = "VisitPageVersions/123",
                                          MetaData = new MetaData {CreatedDate = new DateTime(1975, 8, 6, 0, 14, 0)},
                                          VisitId = "visits/64",
                                          Version = "1"
                                      };

        using (var session = _documentStore.OpenSession())
        {
            session.Store(visitOne);
            session.Store(visitPageVersionOne);
            session.SaveChanges();
        }
    }

    public class MyIndex :
        AbstractMultiMapIndexCreationTask
            <MyIndex.MapReduceResult>
    {
        public const string INDEX_NAME = "MyIndex";

        public override string IndexName
        {
            get { return INDEX_NAME; }
        }

        public class MapReduceResult
        {
            public string VisitId { get; set; }
            public int? MediaSourceId { get; set; }
            public string Version { get; set; }
            public int Count { get; set; }
        }

        public MyIndex()
        {
            AddMap<Visit>(
                visits =>
                from visit in visits
                select new
                           {
                               VisitId = visit.Id,
                               MediaSourceId = (int?) visit.MediaSourceId,
                               Version = (string) null,
                               Count = 1
                           });
            AddMap<VisitPageVersion>(
                visitPageVersions =>
                from visitPageVersion in visitPageVersions
                select new
                           {
                               VisitId = visitPageVersion.VisitId,
                               MediaSourceId = (int?) null,
                               Version = visitPageVersion.Version,
                               Count = 0
                           });
            Reduce =
                results =>
                from result in results
                group result by result.VisitId
                into g
                select
                    new
                        {
                            VisitId = g.Key,
                            MediaSourceId = (int?) g.Select(x => x.MediaSourceId).FirstOrDefault(),
                            Version = g.Select(x => x.Version).FirstOrDefault(),
                            Count = g.Sum(x => x.Count)
                        };
        }
    }
}

最佳答案

您无需执行任何操作即可为可空值提供特殊待遇。 RavenDB 已经可以解决这个问题。

关于map - 在 RavenDB Map/Reduces 中处理可为空字段的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12061274/

相关文章:

c++ - 如何使用映射C++中的值获取匹配键

c++ - 在 Map c++​​ 中对 vector 进行排序

java - Hadoop项目启动时需要的JAR有哪些?

hadoop - 未指定行号时使用 MapReduce 进行矩阵转置

xml - 如何使用 Groovy 的 MarkupBuilder 呈现列表

java - 是否有可能在 hazelcast 中保留一个 map 存储并用于多个 map

views - CouchDB "Join"两个文件

json.net - 从 RavenDB 获取 NServiceBus 订阅

Raven DB 的 Java 客户端 API

lucene - 使用 Where() 查询 Raven 仅过滤前 128 个文档?