RavenDb查询简单的地图变换索引

时间:2013-01-04 15:48:18

标签: ravendb

我一直在努力解决这个问题。

我有一个客户端对象(clients/513),如下所示:

{  
  "Risks": [
    {
      "Id": "421eacf0-14e9-4004-ab0b-95d20e976aac",
      "RiskFactor": "ElectricalEquipment",
      "Description": "Should be allowed to play with electronics."
    },
    {
      "Id": "4bbecbe2-acfc-45c3-b87a-3321e1eca95a",
      "RiskFactor": "ViolenceToStaffVerbal",
      "Description": "Tourettes"
    }
}

我创建了一个包含以下代码的索引:

地图

from c in docs.Clients
from r in c.Risks
select new { ClientId = c.Id, RiskId = r.Id }

变换

from c in results
from r in c.Risks
select new { ClientId = c.Id, RiskId = r.Id }

认为我知道MAP只是定义了您希望能够搜索的属性。并且TRANSFORM以特定形状返回实际数据。

我想要返回ClientId,RiskId以及可能与风险相关的其他一些属性,以便我可以.As<ViewModel>(),但是当我执行查询时,我似乎得到了一些不一致的结果。 (它喜欢改变返回的结果数量,具体取决于执行查询的次数,有时为4次,有时为5次。)

另外:RiskId过滤似乎返回一个,有时多个风险,id不是指定的Id。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:6)

你不需要改造。这是一个对您尝试做的事情更有用的索引:

public class ClientRiskIndex : AbstractIndexCreationTask<Client, ClientRiskResult>
{
    public ClientRiskIndex()
    {
        Map = clients => from c in clients
                         from r in c.Risks
                         select new {
                                        ClientId = c.Id,
                                        RiskId = r.Id,
                                        r.RiskFactor,
                                        r.Description
                                    };

        StoreAllFields(FieldStorage.Yes);
    }
}

这假设一个类结构如下:

public class Client
{
    public string Id { get; set; }
    public IList<Risk> Risks { get; set; }
}

public class Risk
{
    public Guid Id { get; set; }
    public string RiskFactor { get; set; }
    public string Description { get; set; }
}

public class ClientRiskResult
{
    public string ClientId { get; set; }
    public Guid RiskId { get; set; }
    public string RiskFactor { get; set; }
    public string Description { get; set; }
}

现在查询时,您可以执行以下操作:

session.Query<ClientRiskResult, ClientRiskIndex>()
       .Where(x => x.RiskFactor == "ElectricalEquipment")
       .AsProjection<ClientRiskResult>();

如果您想要对风险描述进行全文搜索,只需将此行添加到索引定义中:

Index(x => x.Description, FieldIndexing.Analyzed);

然后你可以像这样搜索:

session.Query<ClientRiskResult, ClientRiskIndex>()
       .Search(x => x.Description, "electronics")
       .AsProjection<ClientRiskResult>();

请注意,通过将数据存储在索引中并从中进行投影,您将获得最终一致的数据&#34;结果。这可能是您描述的结果的来源。您需要留出时间让索引变为非陈旧,或者您需要专门自定义查询以等待。

在现实世界中,您将有足够的时间进行索引以赶上。在您的测试中,请在查询中使用.Customize(x=> x.WaitForNonStaleResults())进行模拟。