该问题可以通过使用带有动态字段的索引来解决。它允许保持逻辑数据结构并避免创建扇出索引。
解决方案
Document
为上述集合创建以下索引:
public class MyIndex : AbstractIndexCreationTask<Document, DocumentIndDto>
{
public MyIndex()
{
// Add fields that are used for filtering and sorting
Map = docs =>
from e in docs
select new
{
Title = e.Title,
_ = e.RecentModifications.Select( x => CreateField ($"{nameof(Document.RecentModifications)}_{x.UserId}", x.Timestamp))
};
}
}
public class DocumentIndDto
{
public string Title { get; set; }
public Dictionary<string,DateTime> RecentModifications { get; set; }
}
MyIndex
点赞查询
var q = s.Query<DocumentIndDto, MyIndex>()
.Where(p => p.Title == "Super" && p. RecentModifications["User1"] < DateTime.Now);
解释
具有动态字段的指定索引将为每条记录生成额外的字段和术语,格式如下:
RecentModifications_User1 = '2018-07-01';
RecentModifications_User2 = '2018-07-02';
格式很重要,因为当您在高级查询(如 )中使用字典时myDic[key]
,它会myDic_key
在生成的 RQL 中转换为。因此,它将允许我们在查询中使用这些字段。
如果您使用通常Query
而不是DocumentQuery
(请参阅文档)进行查询,那么您需要适当的数据类型才能使 LINQ 工作。为此,我创建了DocumentIndDto
类,其中我的RecentModifications
已成为字典,因此我可以在高级查询中使用它并获得正确的 RQL,例如
from index 'MyIndex' where Title = $p0 and RecentModifications_User1 = $p1
有关更多详细信息,请参阅我与 Oren Eini(又名 Ayende Rahien)关于该主题的讨论。