Ebean запрос для строки, которая начинается с, затем содержит определенную строку - PullRequest
0 голосов
/ 18 ноября 2018

У меня возникла небольшая проблема с запросом строки для поиска в БД для функции автозаполнения, проблема, с которой я столкнулся, это то, что мне нужно, чтобы сначала были все операторы, которые «начинаются», а затем операторы, содержащие строка!

Например: если я получил следующие записи в таблице в базе данных:

  1. Потрясающий сервис для обеспечения
  2. Что-то еще здесь
  3. Дополнительные услуги
  4. У меня отличный сервис
  5. Предоставленное обслуживание
  6. Зоопарк

И я начал набирать «Сервис», мне нужно сначала показать № 5, затем остальные пункты (1, 3, 4, 6)

Я знаю, как это сделать в MySQL, что-то вроде:

select * from `services` where `name` like '%Service%' order by `name` like 'Service%' desc;

Или, может быть, как упомянутые здесь способы: MySQL упорядочить по «наилучшему совпадению»

но мне нужно сделать это в Ebean. Я попробовал:

return Service.find.query().where().icontains("name", search).findList()

Но это возвращение с 1, 3, 4, 5, 6,

и теперь я делаю следующее:

final List<Service> list = Service.find.query().where()
            .istartsWith("name", search)
            .orderBy("name").findList(); // First query 

            list.addAll(Service.find.query().where()
            .icontains("name", search)
            .not().istartsWith("name", search)
            .orderBy("name").findList()); // Then add the results for the second query
return list;

Это сделает работу, 5, 1, 3, 4, 6, но мне это не нравится, потому что я попал в базу данных двумя запросами, и я исключаю первый запрос в запросе сложного типа данных во втором запросе. , но в любом случае, это правильный путь? если нет, у вас есть предложение или решение для лучшего пути?

Таблица:

CREATE TABLE `services` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE services ADD UNIQUE `uq_services_name`(name);

Электронное юридическое лицо Service.java:

@Entity
@Table(name = "services")
public class Service extends BaseModel<Service> {
    public static Finder<Integer, Service> find = new Finder<>(Service.class);

    @Column(nullable = false, unique = true)
    private String name;

    // ... setters and getters

}

BaseModel.java:

@MappedSuperclass
public abstract class BaseModel<T> extends Model {

    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    public final Integer getId() {
        return id;
    }

    @SuppressWarnings("unchecked")
    public final T setId(Integer id) {
        this.id = id;
        return (T) this;
    }
}

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Я считаю, что проблема в order by name like 'Service%' desc; части.

  • Вы можете просто использовать findNative (sql)

  • Также недавно было внесено изменение в Ebean, чтобы разрешить произвольные функции в предложении order by, чтобы вы могли попробовать обновить версию Ebean и выполнить:

    .orderBy ("имя как 'Service%' desc"). FindList ();

0 голосов
/ 19 ноября 2018

Мотафар.

Хороший вопрос.Я думаю, вам не нравится ваше решение, потому что оно дважды запрашивает базу данных.Так что насчет запросов сначала, а затем сортировки:

final List<Service> list = Service.find.query().where()
        .icontains("name", search)
        .findList()
        .sort(Comparator.comparingInt(service -> service.getName().indexOf(search)))
);
return list;

Таким образом, сначала идет # 5, а затем остальные, упорядоченные по индексу появления поискового запроса.Предостережение заключается в том, что сортировка не выполняется через базу данных.Но, возможно, можно интегрировать такое условие в предложение orderBy.

Cheers

Jens

...