- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个带有 hibernate、lucene 和 hibernate-search 的 Java 后端。现在我想做一个模糊查询,但不是 0、1 或 2,我想允许查询和预期结果之间存在更多“差异”(以补偿长单词中的拼写错误)。有什么办法可以实现这一点吗?稍后将根据查询的长度计算允许的最大差异。
我想要这个的目的是自动完成搜索并纠正错误字母。此自动完成功能应仅搜索给定查询后面而不是前面的缺失字符。如果与条目相比,查询前面的字符丢失,则应将其计为差异。
示例:本示例中允许的最大不同字符数为 2。fooo
应该匹配
fooo (no difference)
fooobar (only characters added -> autocomplete)
fouubar (characters added and misspelled -> autocomplete and spelling correction)
fooo
不应匹配
barfooo (we only allow additional characters behind the query, but this example is less important)
fuuu (more than 2 differences)
这是我当前的 SQL 查询代码:
FullTextEntityManager fullTextEntityManager = this.sqlService.getFullTextEntityManager();
QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(MY_CLASS.class).overridesForField("name", "foo").get();
Query query = queryBuilder.keyword().fuzzy().withEditDistanceUpTo(2).onField("name").matching("QUERY_TO_MATCH").createQuery();
FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(query, MY_CLASS.class);
List<MY_CLASS> results = fullTextQuery.getResultList();
注释:
1. 我使用 org.apache.lucene.analysis.ngram.EdgeNGramFilterFactory
进行索引,但这不应进行任何更改。
2.这是使用自定义框架,不是开源的。您可以忽略sqlService
,它只提供FullTextEntityManager
并处理hibernate周围的所有事情,不需要每次都自定义代码。
3. 此代码已经可以工作,但仅适用于 withEditDistanceUpTo(2)
,这意味着 QUERY_TO_MATCH
与数据库或索引中的匹配条目之间最多有 2 个“差异”。缺少的字符也算作差异。
4. withEditDistanceUpTo(2)
不接受大于 2 的值。
有人有任何想法来实现这一目标吗?
最佳答案
我不知道有任何解决方案可以指定允许的更改的确切数量。
无论如何,这种方法有严重的缺点:匹配“foo”最多 3 个更改意味着什么?只要匹配任何东西就可以吗?正如您所看到的,适用于不同期限长度的解决方案可能会更好。
一种解决方案是对 n 元词建立索引。我不是在谈论边缘 ngram,就像你已经做的那样,而是从整个术语中提取的实际 ngram,而不仅仅是边缘。因此,当索引 2 克的 foooo
时,您将索引:
fo
oo
(出现多次)查询时,术语fouuu
将转换为:
fo
ou
uu
...它将匹配索引文档,因为它们至少有一个共同术语 (fo
)。
显然有一些缺点。对于 2-gram,术语 fuuuu
不会匹配 foooo
,但术语 barfooo
会匹配,因为它们有一个 2-gram 的共同点。所以你会得到误报。克数越长,出现误报的可能性就越小,但搜索的模糊性也就越低。
您可以通过依靠评分和按分数排序将最佳匹配项放在结果列表中的第一位来消除这些误报。例如,您可以配置 ngram 过滤器以保留原始术语,以便 fooo
将转换为 [fooo
, fo
, oo
] 而不是 [fo
, oo
],因此精确搜索 fooo
将获得更好的分数包含 fooo
的文档比包含 barfooo
的文档(因为有更多匹配项)。您还可以设置多个单独的字段:一个没有 ngram,一个有 3-gram,一个有 2-gram,并为每个字段构建一个带有 on should
子句的 boolean 查询:匹配的子句越多,分数越高,您在点击中找到的文档就越高。
此外,我认为 fooo
和类似的实际上是人为的示例,并且您不太可能在现实世界的数据集中拥有这些术语;你应该尝试针对真实数据集提出的任何解决方案,看看它是否足够好。如果您想要模糊搜索,则必须接受一些误报:问题不在于它们是否存在,而在于它们是否足够稀有,以至于用户仍然可以轻松找到他们正在寻找的内容。
为了使用 ngram,请使用 org.apache.lucene.analysis.ngram.NGramFilterFactory 应用 n-gram 过滤器。在索引和查询时都应用它。使用参数 minGramSize
/maxGramSize
配置 ngram 的大小,并使用 keepShortTerm
(true
/false
)来控制是否保留原始术语。
您可以保留或不保留edge-ngram过滤器;看看它是否提高了结果的相关性?我怀疑如果您使用keepShortTerm = true,可能会稍微提高相关性。无论如何,请确保在 ngram 过滤器之前应用 edge-ngram 过滤器。
关于java - Hibernate搜索模糊超过2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61180101/
什么是 hibernate 和n- hibernate ?我可以在 Visual Studio 2008 中使用它进行 C# Web 应用程序开发吗?请给我建议...我是 asp.net Web 应用
我有一个不系统地发生的异常(exception)。 我试图通过在每次迭代中刷新和清理 session 来解决此问题,但没有成功。 [quartzScheduler_Worker-7] ERROR jd
使用 Hibernate 在数据库中存储 IP 地址的最佳类型是什么? 我虽然是 Byte[] 或 String,但有没有更好的方法,或者你用什么? @Column(name = "range_fr
我正在尝试制定一个公式来选择用户个人资料的用户友好名称。它选择名字 + ' ' + 姓氏 如果其中至少有一个不为空且不为空(包含非空白字符),否则选择 短名称 (条件相同),最后,如果 短名称 为空或
在hibernate中,是否可以将鉴别器作为一个实体?例如,如果我将 Department 作为基类,将 AdminDepartment 和 ProcessingDepartment 作为子类。 De
我只想从表中获取一些列值。因此,我已经使用投影来实现这一目标。该代码有效,但我认为它无效。 我的问题是当我使用ProjectionsList并将标准条件列表设置为ArrayList时-Bulletin
你好: 我对 hibernate 缓存缓存的内容感到困惑。 从文档中,我知道 hibernate 中有缓存类型。 一级 :交易级别。 似乎要被 session 持久化的实体被缓存在这里。 二级缓存 :
我遇到了一个情况: save或update hibernate 的目标表中的某些数据 在目标表上有一个触发器,该触发器将在目标表的insert或update操作之前执行 由 hibernate 将此记
我有一个名为 Master_Info_tbl 的表。它是一个查询表: 这是该表的代码: @Entity @Table(name="MASTER_INFO_T") public class Code
我想知道如何在 Hibernate 查询语言中使用日期文字。我在我的 JPA 项目中做了如下操作(作为 Eclipselink 提供者)并且它工作正常。 SELECT m FROM Me m WHER
@Entity public class Troop { @OneToMany(mappedBy="troop") public Set getSoldiers() { ...
我正在尝试使用 hibernate 查询删除表 'user_role' 中的所有行。但每次我都会出错。有人可以帮我吗。 DaoImpl @Override public void deleteAll(
不是将数据库操作分散在四个 (osgi) 包中,而是在那里做略有不同的事情。我想创建一个负责所有持久性问题的(简单的)OSGi 包。我觉得这并不像听起来那么简单,因为“每个包都有独特的类加载器”。 因
这就是我使用生成器的方式: private Integer id; 我看到的行为是: 创建第一个对象 hibernate 分配 id = 1 删除该对象 关闭服务
对象级别的实体和值类型有什么区别。我知道实体将有一个 id 但值不会,但为什么我们需要不同的方法来映射实体与值类型? 这样做是为了让hibernate可以对值类型应用任何优化吗? 最佳答案 一个实体已
我正在使用 HibernateTemplate.findByCriteria 方法进行一些查询。现在我想在标准上创建一些 SQL 限制,比如 criteria.add(Restrictions.sql
所以我有以下代码: Query query = session.createQuery("from Weather"); List list = query.list();
如何使用Hibernate映射具有多个实体的 View ? 问候, 混沌 最佳答案 请参见Hibernate文档中第5.1.3节“类”,紧接在“Id”节之前: There is no differen
据我所知,Hibernate 有两种类型的实现 JPA的实现(2)(@Entity,@Table注解) 扩展到旧的(传统的) hibernate (没有 JPA),使用 HSQL 查询,没有注释 如果
我需要一个将条目存储为键值对的集合(因此我可以通过键查找值),但我需要一个允许多个值使用 hibernate 共享同一个键的集合 最佳答案 一个键具有多个值的映射称为多映射 - 在 Apache 公共
我是一名优秀的程序员,十分优秀!