简体   繁体   中英

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

I'm doing at the moment a project for university where I'm using the Play! framework 2.4 together with Ebean.

At the moment I'm trying to realize a live user search where a user can search for other users using a fulltext text input. A possible seach string could be "Michael Lee" or just a email address. Im passing the search string to this method where I try to access the database in a smart way:

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);
}

I'm trying to search in the columns firstname , lastname and email for the keyword but play gives me this error:

[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) ]

Is it possible to tell ebean to create the table users with the required fulltext indexes? Or is there a other smart way to search in a MySQL table for a searchstring in many columns? The searchstring can consist keywords from all columns.

Thanks.

Update:

I tried to add an index like it is mentioned in the ebean api doc but unfortunally it seems like the play ebean version does not support the columnNames keyword (and any others at all...).

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

So what else can I do? Is it possible to set this index externally maybe in a second evolution file which is not generated automaticly?

I found a solution using the play framework evolutions. Ebean is creating automatically a first evolution file called 1.sql which contains the full creation of the database schema.

For my users Table the UP part looks like this:

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)
);

As you can see there is no FULLTEXT index created.

What I did is to create a second evolution file 2.sql. This adds a FULLTEXT index to the users table.

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

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

I know it is not the best solution but it is a working one. I'm still interested how other people fix this problem or which solution do you use for a fulltext search.

Your solution is actually good. This is the proper way to handle schema evolutions.

What I normally do is to have the evolutions plugin enabled during development and then disable it when the application is ready - this way you will end up having only 1.sql - at least until you get another change request and decide to update the schema. More info here: https://playframework.com/documentation/2.4.x/Evolutions

Apart from this there is one other thing that you should consider - databases are bad at searching, especially when it comes down to text searches. Some months ago I was in a similar position as I had the requirement to implement such functionality (see https://softwareengineering.stackexchange.com/questions/301843/elasticsearch-and-relational-database-combination ). To spare your time reading it: I ended up using ElasticSearch for handling all my search-related functionality (full text, aggregations, etc.) and I do not regret it! I know that this can be an overkill for your university project but in a real-world scenario you do not want to use your database for full text search.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM