Play 框架:使用 ebean orm 实现全文搜索的最佳方式,因为 @Index 不起作用

Play framework: Best way to implement a fulltext search using ebean orm because of not working @Index

我目前正在做一个大学项目,我正在使用 Play!框架 2.4 与 Ebean 一起。

目前我正在尝试实现实时用户搜索,用户可以在其中使用全文输入搜索其他用户。可能的搜索字符串可以是 "Michael Lee" 或只是一个电子邮件地址。我将搜索字符串传递给此方法,我尝试以一种智能方式访问数据库:

public Result searchUser(String sstring) {
    String query = "WHERE MATCH (firstname,lastname,email) AGAINST ('" + sstring + "' IN BOOLEAN MODE)";
    List<User> resultUsers = User.find
            .setQuery(query)
            .findList();

    String resultString = "";
    for (User user: resultUsers) {
      resultString += user.getFirstname() + user.getLastname() + "<br>";
    }

    return ok(resultString);
}

我试图在 firstnamelastnameemail 列中搜索关键字,但播放时出现此错误:

[PersistenceException: Query threw SQLException:The used table type doesn't support FULLTEXT indexes Bind values:[] Query was: select t0.id c0, t0.firstname c1, t0.lastname c2, t0.birthday c3, t0.email c4, t0.password c5, t0.author c6, t0.points c7, t0.locked c8, t0.last_online c9, t0.date_created c10, t0.date_updated c11 from users t0 where MATCH (t0.firstname,t0.lastname,t0.email) AGAINST ('erik' IN BOOLEAN MODE) ]

是否可以告诉 ebean 使用所需的全文索引创建 table users?或者是否有其他聪明的方法可以在 MySQL table 中搜索许多列中的搜索字符串?搜索字符串可以包含来自所有列的关键字。

谢谢。

更新:

我尝试添加一个索引,就像 ebean api doc 中提到的那样,但不幸的是,play ebean 版本似乎不支持 columnNames 关键字(以及任何其他关键字...)。

@Index(name = "livesearch_index", columnNames = {"firstname","lastname","email"})

那我还能做什么呢?是否可以在外部设置此索引,例如在不是自动生成的第二个进化文件中?

我找到了一个使用 play framework evolutions 的解决方案。 Ebean 正在自动创建一个名为 1.sql 的第一个演变文件,其中包含数据库模式的完整创建。

对于我的 users Table UP 部分如下所示:

create table users (
id                            bigint auto_increment not null,
firstname                     varchar(45),
lastname                      varchar(45),
birthday                      datetime,
email                         varchar(60),
password                      varchar(32),
author                        tinyint(1) default 0,
points                        integer,
locked                        tinyint(1) default 0,
last_online                   datetime,
date_created                  datetime not null,
date_updated                  datetime not null,
constraint uq_users_email unique (email),
constraint pk_users primary key (id)
);

如您所见,没有创建 FULLTEXT 索引。

我所做的是创建第二个进化文件2.sql。这会将 FULLTEXT 索引添加到 users table.

# --- !Ups
create fulltext index livesearch_index on users (firstname,lastname,email);

# --- !Downs
drop index livesearch_index on users;

我知道这不是最好的解决方案,但它是一个可行的解决方案。我仍然对其他人如何解决此问题或您使用哪种解决方案进行全文搜索感兴趣。

你的方案其实很好。这是处理模式演变的正确方法。

我通常做的是在开发期间启用 evolutions 插件,然后在应用程序准备就绪时禁用它 - 这样你最终将只有 1.sql - 至少在你收到另一个更改请求之前并决定更新模式。更多信息在这里:https://playframework.com/documentation/2.4.x/Evolutions

除此之外,您还应该考虑另一件事 - 数据库 不擅长搜索,尤其是涉及到文本搜索时。几个月前,我处于类似的位置,因为我需要实现此类功能(请参阅 https://softwareengineering.stackexchange.com/questions/301843/elasticsearch-and-relational-database-combination)。为了节省您的阅读时间:我最终使用 ElasticSearch 来处理我所有与搜索相关的功能(全文、聚合等),我并不后悔!我知道这对你的大学项目来说可能有点矫枉过正,但在现实世界中你不想使用你的数据库进行全文搜索。