首页 > 解决方案 > RavedDB“外部连接”

问题描述

我的 ravenDB 中有 2 个文档集合,位置和地址如下所示:

public class Location()
{
    public string Id{get;set;}
    public string Name{get;set;}
    public List<Address> Addresses{get;set;}

}

public class Address()
{
    public string Id{get;set;}
    public string StreetName {get;set;}
    public string PostalCode {get;set;}
}

所以一个位置可以有零个或多个地址。而且我可以有许多未分配给位置的地址。

如果我有这样的数据:

//2 Location document
{
Id:"Location/1",
Name: "My Location 1"
Addresses: [{id:"Address/1"},
            {id:"Address/2"}
            ]
}

{
Id:"Location/2",
Name: "My Location 2"
Addresses: [
            {id:"Address/2"}
            ]
}


//3 Address document
{
Id: "Address/1",
StreetName: "Street1 10",
PostalCode: "1000"
}

{
Id: "Address/2",
StreetName: "Street1 11",
PostalCode: "1000"
}

{
Id: "Address/3",
StreetName: "Street1 12",
PostalCode: "2000"
}

我正在努力寻找创建索引的最佳方法,这将为我提供如下结果集:

StreetAddress PostalCode    Location
Street1 10  1000    My Location 1
Street2 11  1000    My Location 2
Street2 11  1000    My Location 1
Street3 12  2000

我将不胜感激对此的任何意见:-)

标签: ravendb

解决方案


一种选择是反过来建模,即

public class Location()
{
    public string Id {get;set;}
    public string Name {get;set;}

}

public class Address()
{
    public string Id {get;set;}
    public string StreetName {get;set;}
    public string PostalCode {get;set;}
    // Locations is a list with the Location documents IDs
    public List<string> Locations {get;set;}

}

然后索引可以是:

from address in docs.Addresses
select new {
     StreetAddress = address.StreetName,
     PostalCode = address.PostalCode
}

然后使用以下查询

from index 'AddressesIndex' as x
load x.Locations as locations[]
select {
      StreetName: x.StreetName,
      PostalCode: x.PostalCode,
      Locations: locations.map(x => x.Name)
}

==================================================== ==========================

第二种选择是使用与问题描述中相同的模型
并定义多图归约索引。

multi-map-reduce索引将是:

第一张地图:

from locationDoc in docs.Locations
from addressId in locationDoc.Addresses
let address = LoadDocument(addressId, "Addresses")
select new {
       StreetName = address.StreetName,
       PostalCode = (string)null,
       LocationNames = new []{locationDoc.Name},
}

第二张地图:

from address in docs.Addresses
select new{
       StreetName = address.StreetName,
       PostalCode = address.PostalCode,
       LocationNames = (string)null
}

减少:

from result in results
group result by new { result.StreetName } into g
select new {
       StreetName = g.Key.StreetName,
       PostalCode = g.Select(x => x.PostalCode).FirstOrDefault(x => x != null),
       LocationNames = g.SelectMany(x => x.LocationNames)
}

推荐阅读