RavenDB 查询文档未在相关文档中引用
RavenDB query documents NOT referenced in related document
public class LedgerItem
{
public string Id { get; set; }
...
}
public class Order
{
...
public IList<OrderLine> OrderLines { get; private set; }
...
}
public class OrderLine
{
...
public List<string> LedgerItemIds { get; set; }
...
}
我需要在任何 Order.OrderLines.LedgerItemIds.
中找到所有未被 Id 引用的 LedgerItems
到目前为止,我已尝试为 LedgerItems 和 Orders 中的所有 LedgerItems 创建 Multi-Map/Reduce 索引,然后按 LedgerItemId 归约并汇总计数。
然后我的计划是通过 Count == 1 进行查询,因为这意味着它在组中只存在一次。
public class LedgerItemResult
{
public string Id { get; set; }
public DateTime CreatedDate { get; set; }
public string ProTeriaCustomerId { get; set; }
public string Collection { get; set; }
public int Count { get; set; }
}
public class LedgerItemsFromLedgerItemsAndOrdersGroupById : AbstractMultiMapIndexCreationTask<LedgerItemResult>
{
public LedgerItemsFromLedgerItemsAndOrdersGroupById()
{
AddMap<LedgerItem>(
ledgeritems => from ledgeritem in ledgeritems
where (decimal)ledgeritem.Amount < 0m
select new
{
Id = ledgeritem.Id,
CreatedDate = ledgeritem.TimeStamp,
ProTeriaCustomerId = ledgeritem.ProTeriaCustomerId,
Collection = MetadataFor(ledgeritem)["Raven-Entity-Name"].ToString(),
Count = 1
}
);
AddMap<Order>(
orders => from order in orders
from orderline in order.OrderLines
from ledgeritemid in orderline.LedgerItemIds
select new
{
Id = ledgeritemid,
CreatedDate = order.CreatedDateTime,
ProTeriaCustomerId = order.ProTeriaCustomerId,
Collection = MetadataFor(order)["Raven-Entity-Name"].ToString(),
Count = 1
}
);
Reduce = results =>
from result in results
group result by result.Id into g
select new LedgerItemResult
{
Id = g.First().Id,
CreatedDate = g.First().CreatedDate,
ProTeriaCustomerId = g.First().ProTeriaCustomerId,
Collection = g.First().Collection,
Count = g.Sum(x => x.Count)
};
Stores.Add(x => x.Id, FieldStorage.Yes);
Stores.Add(x => x.CreatedDate, FieldStorage.Yes);
Stores.Add(x => x.ProTeriaCustomerId, FieldStorage.Yes);
Stores.Add(x => x.Collection, FieldStorage.Yes);
MaxIndexOutputsPerDocument = 250;
}
}
虽然这似乎无法正常工作。我尝试查询 Count == 1 和 Count == 2,得到的 Count == 1 的结果太多了,我手动检查了返回的 LedgerItemIds 之一,看看它是否真的被订单引用了,虽然它确实被引用了不应该。
可能有更简单的方法来实现这一点,但我仍然有点习惯于 SQL。
我希望找到一种方法来完成此操作,以便我可以在 Management Studio 中使用 Lucene 语法查询索引,也可以在代码中使用 LiINQ。
原来我是在正确的轨道上,但被骗了一段时间,因为磁盘快满了。它可能越过了 "stop indexing when too little disk space"-treshold,而索引是 运行 并且创建的索引不一致。
public class LedgerItem
{
public string Id { get; set; }
...
}
public class Order
{
...
public IList<OrderLine> OrderLines { get; private set; }
...
}
public class OrderLine
{
...
public List<string> LedgerItemIds { get; set; }
...
}
我需要在任何 Order.OrderLines.LedgerItemIds.
中找到所有未被 Id 引用的 LedgerItems到目前为止,我已尝试为 LedgerItems 和 Orders 中的所有 LedgerItems 创建 Multi-Map/Reduce 索引,然后按 LedgerItemId 归约并汇总计数。 然后我的计划是通过 Count == 1 进行查询,因为这意味着它在组中只存在一次。
public class LedgerItemResult
{
public string Id { get; set; }
public DateTime CreatedDate { get; set; }
public string ProTeriaCustomerId { get; set; }
public string Collection { get; set; }
public int Count { get; set; }
}
public class LedgerItemsFromLedgerItemsAndOrdersGroupById : AbstractMultiMapIndexCreationTask<LedgerItemResult>
{
public LedgerItemsFromLedgerItemsAndOrdersGroupById()
{
AddMap<LedgerItem>(
ledgeritems => from ledgeritem in ledgeritems
where (decimal)ledgeritem.Amount < 0m
select new
{
Id = ledgeritem.Id,
CreatedDate = ledgeritem.TimeStamp,
ProTeriaCustomerId = ledgeritem.ProTeriaCustomerId,
Collection = MetadataFor(ledgeritem)["Raven-Entity-Name"].ToString(),
Count = 1
}
);
AddMap<Order>(
orders => from order in orders
from orderline in order.OrderLines
from ledgeritemid in orderline.LedgerItemIds
select new
{
Id = ledgeritemid,
CreatedDate = order.CreatedDateTime,
ProTeriaCustomerId = order.ProTeriaCustomerId,
Collection = MetadataFor(order)["Raven-Entity-Name"].ToString(),
Count = 1
}
);
Reduce = results =>
from result in results
group result by result.Id into g
select new LedgerItemResult
{
Id = g.First().Id,
CreatedDate = g.First().CreatedDate,
ProTeriaCustomerId = g.First().ProTeriaCustomerId,
Collection = g.First().Collection,
Count = g.Sum(x => x.Count)
};
Stores.Add(x => x.Id, FieldStorage.Yes);
Stores.Add(x => x.CreatedDate, FieldStorage.Yes);
Stores.Add(x => x.ProTeriaCustomerId, FieldStorage.Yes);
Stores.Add(x => x.Collection, FieldStorage.Yes);
MaxIndexOutputsPerDocument = 250;
}
}
虽然这似乎无法正常工作。我尝试查询 Count == 1 和 Count == 2,得到的 Count == 1 的结果太多了,我手动检查了返回的 LedgerItemIds 之一,看看它是否真的被订单引用了,虽然它确实被引用了不应该。
可能有更简单的方法来实现这一点,但我仍然有点习惯于 SQL。
我希望找到一种方法来完成此操作,以便我可以在 Management Studio 中使用 Lucene 语法查询索引,也可以在代码中使用 LiINQ。
原来我是在正确的轨道上,但被骗了一段时间,因为磁盘快满了。它可能越过了 "stop indexing when too little disk space"-treshold,而索引是 运行 并且创建的索引不一致。