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