这是一个带有Hibernate搜索的Spring Boot,底层数据库是MySQL。
主实体Article
有一组子实体:Set<Price>
.
每个Price
都有一个Country
实体、Store
实体、数字amount
和可选date-begin
以及可选date-end
的链接。日期用于表示一段时间内的折扣(如果有)。
是否有一种方法来索引Article
实体,以便发出一个搜索,将返回只有 * 活动 * 价格的文章(这将是没有日期的"永久"价格,也是基于当前或任何其他给定日期匹配日期范围的价格)。
例如:
Article #1
Price: US, $100
Price: DE, €100, from 2023-12-25 to 2023-12-31
Price: IT, €100, from 2024-01-01
Article #2
Price: DE, €50, to 2023-12-31
如何获取DE国家的所有有效价格的文章?
如果日期为今天,预期结果将是一篇文章(#2),因为第一篇文章的DE价格将在很久以后生效,应在搜索中跳过。
Lucene应该做这项工作,因为有许多搜索选项(这里没有提到)会创建一个怪物SQL查询。当索引文章时,许多信息是从其他链接表添加的,如Set<Tag>
(每篇文章可以有无限数量的标签),Category
name,这样你就可以搜索"body milk",并获得自己名称中没有"body milk"的产品。
每篇文章都有单独的文本字段searchAid
,我把一些关键字,以帮助搜索过程(例如,如果文章名称是"糖果棒",在搜索帮助我把"酒吧",然后你得到它时,搜索"糖果棒")。
此外,还添加了Provider
名称和City
名称以及街道名称,以便您可以按地址搜索。
还有更多的细节更不用说所有。
最后,我添加了Article
名称的所有翻译,这样你就可以用任何语言搜索并获得想要的文章。
一开始,使用Hibernate通过QueryDSL
完成此工作,但在配备2x m2-SSD和64GB DDR4的i9开发机器上,仅使用100个测试项目运行自动创建的查询需要10秒以上。
在SQL中,所需的Lucene查询应满足以下条件,稍后可通过附加过滤(通过标签和任何其他所需条件)进行扩展:
SELECT
JSON_EXTRACT(art.name, '$.hr_HR'),
pri.amount,
cur.java_currency,
cou.alpha2,
JSON_EXTRACT(cit.name, '$.hr_HR'),
pri.local_date_time_valid_from,
pri.local_date_time_valid_to,
pri.zone_id_valid_from_to
FROM article art
LEFT JOIN price_info pri ON pri.article_id = art.id
LEFT JOIN provider pro ON pro.id = pri.provider_id
LEFT JOIN city cit ON cit.id = pro.city_id
LEFT JOIN country cou ON cou.id = cit.country_id
LEFT JOIN custom_currency cur ON cur.id = pri.currency_id
WHERE
cou.alpha2 = 'DE'
AND
pri.amount IS NOT NULL
AND (
pri.local_date_time_valid_from IS NULL
OR
pri.local_date_time_valid_from >= STR_TO_DATE('2021-01-01','%Y-%m-%d')
)
AND (
pri.local_date_time_valid_to IS NULL
OR
pri.local_date_time_valid_to <= STR_TO_DATE('2022-01-01','%Y-%m-%d')
);
1条答案
按热度按时间4xrmg8kj1#
是否有一种方法可以索引文章实体,以便进行搜索,仅返回具有有效价格的文章(这将是没有日期的“永久”价格,也是基于当前或任何其他给定日期匹配日期范围的价格)。
使用Hibernate Search 6,是的。您将需要嵌套文档,以便在搜索时您可以表达这样的意图:“我希望今天介于 same price的开始日期和结束日期之间,并且 same price必须是针对国家DE的”。
对于Hibernate Search 5,我不知道有什么解决方案。