0

这篇文章在某种程度上回答了这个问题(我稍后会包括答案),但我希望能得到更多的细节。

我们有许多应用程序,每个应用程序都需要以自己的方式访问/操作来自 Raven 的数据。数据仅通过主 Web 应用程序写入。其他应用程序包括批处理式任务、报告等。为了使这些中的每一个尽可能地分离,它们是单独的解决方案。

在这种情况下,我如何从报告应用程序中使用本地定义的类型在现有数据上创建索引?

来自链接问题的答案状态

只要您要反序列化的类的结构与数据的结构部分匹配,它就不会产生影响。

RavenDB 服务器根本不关心您在客户端使用什么类。如果您针对不同的平台,您当然可以共享一个 dll,甚至共享一个可移植的 dll。但是你是对的,没有必要。

但是,您应该了解 Raven-Clr-Type 元数据值。RavenDB 客户端在存储原始文档时会设置此项。它被客户端消耗回来以协助反序列化,但它没有完全强制执行

这是我想要澄清的第一部分。服务器上文档的对象图和我的应用程序中的类型是否必须完全匹配?如果服务器上的 Click 文档是

{
  "Visit": {
    "Version": "0",
    "Domain": "www.mydomain.com",
    "Page": "/index",
    "QueryString": "",
    "IPAddress": "127.0.0.1",
    "Guid": "10cb6886-cb5c-46f8-94ed-4b0d45a5e9ca",
    "MetaData": {
      "Version": "1",
      "CreatedDate": "2012-11-09T15:11:03.5669038Z",
      "UpdatedDate": "2012-11-09T15:11:03.5669038Z",
      "DeletedDate": null
    }
  },
  "ResultId": "Results/1",
  "ProductCode": "280",
  "MetaData": {
    "Version": "1",
    "CreatedDate": "2012-11-09T15:14:26.1332596Z",
    "UpdatedDate": "2012-11-09T15:14:26.1332596Z",
    "DeletedDate": null
  }
}

是否可以(如果可以,如何?)从我的应用程序创建一个 Map 索引,它定义 Click 类如下?

class Click
{
    public Guid Guid {get;set;}
    public int ProductCode {get;set;}
    public DateTime CreatedDate {get;set;}
}

还是我的班级必须看起来像这样?(其中自定义类型被定义为上述文档中属性的子集,具有匹配的属性名称)

class Click
{
    public Visit Visit {get;set;}
    public int ProductCode {get;set;}
    public MetaData MetaData {get;set;}
}

更新

从下面的答案开始,这是我设法开始工作的代码。

指数

public class Clicks_ByVisitGuidAndProductCode : AbstractIndexCreationTask
{
    public override IndexDefinition CreateIndexDefinition()
    {
        return new IndexDefinition
            {
                Map =
                    "from click in docs.Clicks select new {Guid = click.Visit.Guid, ProductCode = click.ProductCode, CreatedDate = click.MetaData.CreatedDate}",
                TransformResults =
                    "results.Select(click => new {Guid = click.Visit.Guid, ProductCode = click.ProductCode, CreatedDate = click.MetaData.CreatedDate})"
            };
    }
}

询问

var query = _documentSession.Query<ReportClick, Clicks_ByVisitGuidAndProductCode>()
                            .Customize(x => x.WaitForNonStaleResultsAsOfNow())
                            .Where(x => x.CreatedDate >= start.Date && x.CreatedDate < end.Date);

点击在哪里

public class Click
{
    public Guid Guid { get; set; }
    public int ProductCode { get; set; }
    public DateTime CreatedDate { get; set; }
}

非常感谢@MattJohnson。

4

1 回答 1

1

该形状是部分匹配的,然后它将填充它可以填充的位置,因此您的第二个示例可以正常工作。

但是,您可以创建一个索引来预测您在第一个示例中显示的结果。您将根据实际要过滤或排序的任何内容进行映射,然后添加一个 TransformResults 部分:

TransformResults = (database, clicks) =>
    from click in clicks
    select new {
        click.Visit.Guid,
        click.ProductCode,
        click.MetaData.CreatedDate
    };

当您查询此索引时,它将以您在转换中指定的形状出现。这是一个称为“实时投影”的功能,您可以在此处阅读更多信息。(您不需要.As()打电话,只需使用.Query<Click, YourIndex>()它应该可以正常工作。)

另外——你用 MetaData 做什么是无关紧要的。Raven 将元数据与文档分开。在此处阅读有关元数据的更多信息。

看起来你有版本问题。如果您只是保留审计线索,您应该查看 Raven 的标准版本控制包。如果您有时间有效性问题,请考虑使用我的新Temporal Versioning Bundle

于 2012-12-10T20:22:15.170 回答