c# - RavenDb 索引对嵌套结构/集合的属性进行过滤和排序(扇出索引)
问题描述
我正在寻找一种创建静态索引的方法,以便为嵌套结构(对象集合)中的属性值组合以及结构容器提供过滤/排序查询。由于以下原因,这似乎并非微不足道:
给定以下持久模型:
public class Document
{
public string Title { get; set; }
public List<UserChange> RecentModifications { get; set; }
}
在哪里
public class UserChange
{
public string UserId { get; set; }
public DateTime Timestamp { get; set; }
}
问题:如何构建索引Document
以通过所有字段的组合进行过滤/排序Title
:UserId
和Timestamp
?
可能的用例:
- 获取包含特定用户和日期范围的“合同”一词的所有文档
- 按用户最后一次修改对包含单词“contract”的文档进行排序。
PS我知道可以通过重构持久性模型来绕过索引限制 - 在文档中存储最近修改的文档的结构User
,但它会施加一些其他限制,我想避免这些限制。
解决方案
该问题可以通过使用带有动态字段的索引来解决。它允许保持逻辑数据结构并避免创建扇出索引。
解决方案
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)关于该主题的讨论。
推荐阅读
- sql - 由于多列信息不同,对所有行进行标记;水晶报表
- python-3.x - 为什么 python 脚本运行时的结果在每个解释器上都不同,包括类方法/属性?
- c# - UnassignedReferenceException: Player 的变量 rb 没有被赋值
- python - 在 Python 中使用 writelines 将行添加到文件中还会复制不同位置的行吗?
- python - 在 Docker 中配置/设置/激活 Python Conda 环境
- javascript - Console.log 在 Chrome 控制台中未显示任何内容。(反应)
- javascript - 在本地显示 mbtiles 文件
- python - 尝试删除括号“[...]”内的每个字符
- javascript - 有没有一种简单的方法可以从提供级别/节点信息的数组构造结构化对象(带有嵌套对象)?
- python - 从 pandas 的 DF 列中的列表中删除非数字