mongodb - 跨时间的多标准搜索
问题描述
我正在寻找一种优雅且可扩展的方式来跨时间搜索某些实体的元信息。
让我们看一下实体 A 和 B 随时间变化的以下元数据
[{
"idEntity": "A",
"name": "Name of A",
"rating": 0.5,
"description": "Some short description of A",
"createdAtWeek": 1
}, {
"idEntity": "B",
"name": "Name of B",
"rating": 0.2,
"description": "Some short description of B",
"createdAtWeek": 1
}, {
"idEntity": "A",
"name": "Name of A improved",
"rating": 0.5,
"description": "Some longer description of A",
"createdAtWeek": 2
}, {
"idEntity": "A",
"name": "Name of A improved",
"rating": 0.6,
"description": "Some longer description of A",
"createdAtWeek": 3
}]
我希望能够找到最后一个元匹配的实体(唯一)rating >= 0.2
并且of
在它们的description
. 我也希望能够过去寻找这些相同的标准,但这需要给我不同的结果。
通过 Mongo 进行此操作的最简单方法是创建一个聚合管道,但如果集合变得越来越大,这将太慢。
因此,我去复制了所有文档,以便每周 (1-3) 获得完整的数据,这使我可以createdAtWeek
直接将其包含在查询中,并确保我在不同时间获得一致的结果。
但是你可以看到这会导致什么,巨大的重复使收藏变得一文不值。
因此,我尝试将这些文档存储在 Solr 中,但是在查看文档时,似乎没有办法首先按实体和日期对结果进行分组,然后在分组中进行搜索。
是否有另一种方法可以在不实际复制的情况下实现与复制相同的结果?
解决方案
Solr Block Join Query Parser 可以处理这种操作。
数据结构向分层系统变化,createdAtWeek
并被替换为validSince_i
和validUntil_i
。
/* Entity A */
{
"path_s": "1.entity",
"id": "A",
"_childDocuments_": [
{
"path_s": "2.metadata.rating",
"id": "2.metadata.rating.1",
"_childDocuments_": [
{
"path_s": "3.metadata.rating.timeValidity",
"id": "2.metadata.rating.timeValidity.1",
"validSince_i": -1,
"validUntil_i": 2,
"value_f": 0.5
},
{
"path_s": "3.metadata.rating.timeValidity",
"id": "2.metadata.rating.timeValidity.2",
"validSince_i": 3,
"validUntil_i": 9999999,
"value_f": 0.6
}
]
},
{
"path_s": "2.metadata.description",
"id": "2.metadata.description.1",
"_childDocuments_": [
{
"path_s": "3.metadata.description.timeValidity",
"id": "2.metadata.description.timeValidity.1",
"validSince_i": -1,
"validUntil_i": 1,
"value_txt_en": "Some short description of A"
},
{
"path_s": "3.metadata.description.timeValidity",
"id": "2.metadata.description.timeValidity.2",
"validSince_i": 2,
"validUntil_i": 9999999,
"value_txt_en": "Some longer description of A"
}
]
}
]
}
/* Entity B */
{
"path_s": "1.entity",
"id": "B",
"_childDocuments_": [
{
"path_s": "2.metadata.rating",
"id": "2.metadata.rating.2",
"_childDocuments_": [
{
"path_s": "3.metadata.rating.timeValidity",
"id": "2.metadata.rating.timeValidity.3",
"validSince_i": -1,
"validUntil_i": 9999999,
"value_f": 0.2
}
]
}
]
}
BlockJoin 现在可以与 faceting 一起使用,只要 timeValidities 没有像这样相互重叠:
fq={!parent which="path_s:1.entity"}(path_s:3.metadata.rating.timeValidity AND validUntil_i:[2 TO *] AND value_f:[0.3 TO *])&fq={!parent which="path_s:1.entity"}(path_s:3.metadata.description.timeValidity AND validUntil_i:[2 TO *] AND value_txt_en:short)&q=*:*
它不返回任何实体,因为在第 2 周之后没有实体rating >= 0.3
的描述包含short
运行以下工作也很好
fq={!parent which="path_s:1.entity"}(path_s:3.metadata.rating.timeValidity AND validUntil_i:[2 TO *] AND value_f:[0.3 TO *])&fq={!parent which="path_s:1.entity"}(path_s:3.metadata.description.timeValidity AND validUntil_i:[2 TO *] AND value_txt_en:longer)&q=*:*
如您所见,实体 A 显示为在一周 >= 2 后其评级 >= 0.3 且描述包含longer
.
需要声明性能方面,但它可以完成工作并避免重复。
推荐阅读
- mysql - 如何将使用 IF 语句的查询修复到 WHERE 条件中?
- php - 除非使用 WP_Query,否则不会出现 WooCommerce 产品
- scipy - scipy integration.quad 返回不正确的值
- java - 在java中为没有ID的Android元素创建Xpath
- python - 我们如何在不创建 SSH 连接的情况下以编程方式从受密码保护的私钥中获取公钥?
- sd-card - 带 SPI 的 SDHC 卡
- variables - 找出 Pyomo 模型不可行的原因
- xml - 如何在 Excel 中使用 VBA 导入 XML 文件名和数据?
- android - 回收站视图中部分项目的动画
- spring - 在 Spring Rest 中创建银行应用程序(2 个用例)时抛出哪个异常?