跳转到内容

TSQL用户指南

1. 数据增删改

搜索模型数据的增删改和普通模型一样,只是数据会被DS通过同步把数据同步到ES上,搜索模型主要的功能还是查询。 同步分为增量同步和全量同步,操作方法请查看概念理解---DS-Search概念文档。

2. 查询API

查询搜索模型有两种方式,一是TSQL方式,一种是SearchQuery方式。

  • 和普通的TSQL查询一样的方式,不支持ES的高级功能。(比如权重,地理位置,分词器等)
  • SearchQuery使用的是ES原生的DSL语法,如果你对DSL语法熟悉,理论上是可以实现ES支持的所有的功能。

2.1 API 使用示例

文档中会举例一些简单场景,分别列出TSQL方式和SearchQuery方式对该场景的实现。 示例中TSQL的实现方式使用的是手拼Tsql方式,业务也可以根据喜好选择TSQL-DSL方式。 下文的查询语句会以搜索模型ItemSO举例。

搜索模型ItemSO的模型定义:

@Data
@SearchModel(name = "Item search model")
@Model(name = "Item")
public class ItemSO extends BaseModel<Long> {
@Field(name = "Item name")
private String itemName;
@Field(name = "Item number")
private String itemNumber;
@Field(name = "Item type")
@DictionaryMeta(ItemTypeDict.class)
private String itemType;
@Field(name = "Item price")
private BigDecimal itemPrice;
@Field(name = "CategoryBO模型的id列表", type = FieldType.Json)
private List<Long> categoryIds;
@Field(name = "CategoryBO模型的name列表", type = FieldType.Json)
private List<String> categoryNames;
//地理位置类型,此字段表示一个坐标点
@Field(name = "Item GeoLocation")
private GeoLocation itemGeoLocation;
//地理位置类型,此字段表示一个区域(区域下有三个子类: 矩形,圆形,多边形)
@Field(name = "Item GeoArea")
private GeoArea itemGeoArea;
}

2.1.1 根据id搜索

TSQL 实现方式

String select = "*";
String where = "id=1";
Paging<ItemSO> itemSOList=Search.paging(ItemSO.class,select,where,new Page(0,20));

SearchQuery 实现方式

SearchQuery searchQuery = new SearchQuery();
searchQuery.where(f -> f.bool()
.must(f.idsQuery("1"));
Paging<ItemSO> itemSOList=Search.searchDSL(ItemSO.class,new Page(0,20),searchQuery);

生成的T-SQL

select * from `ItemSO` where `id` = 1 limit 0,20

实际转化的的SQL

select * from `Item_s_o` where ( `id` = 1 ) AND `isDeleted` = 0 limit 0,20;

2.1.2 模糊查询

TSQL 实现方式

String select = "*";
String where = "itemName = '姓名' or description like '%描述%'";
Paging<ItemSO> itemSOList=Search.paging(ItemSO.class,select,where,new Page(0,20));

SearchQuery 实现方式

SearchQuery searchQuery = new SearchQuery();
searchQuery.where(f -> f.bool()
.must(f.matchQuery("itemName","姓名"))
.should(f.wildcardQuery("description","描述"));
Paging<ItemSO> itemSOList=Search.searchDSL(ItemSO.class,new Page(0,20),searchQuery);

生成的T-SQL

select * from `ItemSO` where itemName = '姓名' or description like '%描述%' limit 0,20

实际转化的的SQL

select * from `Item_s_o` where ( itemName = '姓名' or description like '%描述%' ) AND `isDeleted` = 0 limit 0,20;

2.1.3 根据字段分组

TSQL 实现方式

String sql = "select count(*) as count from Item_s_o where itemName = '姓名' group by itemType";
List<Map<String, Object>> map=Search.find(sql);

SearchQuery 实现方式

SearchQuery searchQuery = new SearchQuery();
searchQuery.where(f -> f.bool()
.must(f.matchQuery("itemName","姓名")))
.aggregation(a->a.terms("itemTypeAlias","itemType"));
List<Map<String, Object>> map=Search.find(ItemSO.class,searchQuery);

生成的T-SQL

select count(*) as count from `ItemSO` where itemName = '姓名' group by itemType limit 0,20

实际转化的的SQL

select count(*) as count from `Item_s_o` where ( itemName = '姓名' ) AND `isDeleted` = 0 group by itemType limit 0,20;

2.1.4 根据字段排序

TSQL 实现方式

String select = "*";
String where = "itemName = '姓名' order by itemPrice desc";
Paging<ItemSO> itemSOList=Search.paging(ItemSO.class,select,where,new Page(0,20));

SearchQuery 实现方式

SearchQuery searchQuery = new SearchQuery();
searchQuery.where(f -> f.bool()
.must(f.matchQuery("itemName","姓名")))
.sort("itemPrice",Order.DESC));
Paging<ItemSO> itemSOList=Search.searchDSL(ItemSO.class,new Page(0,20),searchQuery);

生成的T-SQL

select * from `ItemSO` where itemName = '姓名' order by itemPrice desc limit 0,20

实际转化的的SQL

select * from `Item_s_o` where ( itemName = '姓名' ) AND `isDeleted` = 0 order by itemPrice desc limit 0,20;

ES支持的高级功能

目前TSQL无法支持ES支持的功能,比如下面的权重和地理位置等。可以通过SearchQuery方式来实现。

搜索条件添加权重写法

//查询itemImage不为null(权重为2)和itemPrice=100(权重为1)的所有数据。
SearchQuery searchQuery = new SearchQuery();
searchQuery.where(f -> f.bool()
.must(f.existsQuery("itemImage").boosts(2.00f))
.should(f.matchQuery("itemPrice", 100)));
Paging<ItemSO> itemSOList=Search.searchDSL(ItemSO.class,new Page(0,20),searchQuery);

给定一个地理形状,搜索出覆盖该坐标的多边形列表

给定一个矩形
SearchQuery searchQuery=new SearchQuery();
//根据俄下面的type类型设置,coordinates表示一个矩形
List<DSGeoLocation> coordinates=new LinkedList<>();
coordinates.add(new DSGeoLocation(100.3, 1.0));//左上角坐标点
coordinates.add(new DSGeoLocation(101.0, 0.0));//右上角坐标点
searchQuery.where(a->a.bool()
.must(a.termsQuery("itemNumber",10,20).boosts(2.00f))
.filter(a.geoShapeSearch("itemGeoArea")
.relation(ShapeRelation.contains) //表示搜索出覆盖coordinates的itemGeoArea
.locations(coordinates)
.type(ShapeType.envelope)));//表示coordinates的形状是一个矩形
Paging<ItemSO> itemSOList=Search.searchDSL(ItemSO.class ,new Page(0,20),searchQuery);
给定一个多边形
SearchQuery searchQuery=new SearchQuery();
//根据俄下面的type类型设置,coordinates表示一个三角形(特殊的多边形)
List<DSGeoLocation> coordinates=new LinkedList<>();
coordinates.add(new DSGeoLocation(100.3, 0.0));
coordinates.add(new DSGeoLocation(101.0, 1.0));
coordinates.add(new DSGeoLocation(100.0, 2.0));
coordinates.add(new DSGeoLocation(100.3, 0.0));
searchQuery.where(a->a.bool()
.must(a.termsQuery("itemNumber",10,20).boosts(2.00f))
.filter(a.geoShapeSearch("itemGeoArea")
.relation(ShapeRelation.contains) //表示搜索出覆盖coordinates的itemGeoArea
.locations(coordinates)
.type(ShapeType.polygon)));//表示coordinates的形状是一个多边形
Paging<ItemSO> itemSOList=Search.searchDSL(ItemSO.class ,new Page(0,20),searchQuery);

给定坐标点,根据坐标点之间距离排序

// WarehouseSo是一个仓库搜索模型
SearchQuery searchQuery = new SearchQuery();
searchQuery.where(a -> a.bool().must(a.termsQuery("itemNumber",1,2)))
.geoDistanceSort(s->s.field("itemGeoArea")
.location(120.174381,31.254079)
.order(Order.ASC)
//unit代表返回距离的单位。
.unit(UnitEnum.km));
Search.paging(WarehouseSo.class ,searchQuery);