我有一个小问题,这里有一个字符串查询数据库中搜索自动完成功能,我得到了我需要第一的成绩是所有陈述,“开始”,然后用含有该字符串的语句的问题!
例如:如果我在数据库中的表有以下记录:
- 真棒服务提供
- 别的东西在这里
- 额外服务
- 我的服务是真棒
- 提供服务
- 动物园服务
我开始键入“服务”我需要5号第一次表明,则物品的其余部分(1,3,4,6)
我知道该怎么做在MySQL,是这样的:
select * from `services` where `name` like '%Service%' order by `name` like 'Service%' desc;
或者,也许喜欢这里提到的方法:MySQL order by "best match"
但我需要做的是,在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,但我不喜欢它,因为我打数据库查询2,也是我不排除在第二个查询中复杂的数据类型的查询第一个查询,但不管怎么说,它是一个正确的方式?如果没有,你有更好的方法建议或解决方案?
表:
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);
EBean实体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
}
base model.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;
}
}
我相信这个问题是order by name like 'Service%' desc;
一部分。
Motfr。
这是个好问题。我猜你不喜欢你的解决方案,因为它查询数据库两次。那么,关于第一查询,然后再把排序:
final List<Service> list = Service.find.query().where()
.icontains("name", search)
.findList()
.sort(Comparator.comparingInt(service -> service.getName().indexOf(search)))
);
return list;
这样,#5是第一位的,然后由检索词的出现指数下令休息。需要说明的是,排序不通过数据库来完成。但是,也许有可能这样的条件融入ORDERBY子句。
干杯
延