ES中模糊查询的实现
业务场景:
一个树形架构,承载了小区的数据,4层结构,如下图所示
XX小区
--- XXX 号楼
--- XXX 单元
---- XXX房间
每个节点都有一个唯一的SpaceId,页面下拉树形结构,选中任何层级(比如选中5号楼),能查询出5号楼下面的所有单元+房间
数据存储在ES中,方案1:
房屋数据冗余一个字段longSpaceId,含义:当前房屋的所有层级spaceId
比如:101房间的spaceId=1234,他的父节点space=222,爷爷节点spaceId=12,顶级节点spaceId=1,那该值=,1,12,222,1234,
很容易理解把,我们根据选中的任意空间ID做个like查询就行
GET face_platform_go_through_record/_search { "size": 100, "sort": [ { "recordTime": { "order": "desc" } } ], "query": { "bool": { "must": [ { "match": { "actionType": "1" } }, { "wildcard": { "longSpaceId": { "value": "*1022*" } } } ] } } }
java代码实现如下:
qb2.must(QueryBuilders.wildcardQuery("longSpaceId", "*"+req.getSpaceId().toString()+"*"));
问题二:该小区有50栋楼,每个楼长负责2栋楼,默认查询它负责的两栋楼的数据
解决方案:新增字段longSpaces:以数组的形式存放每栋楼的所有spaceid,简单说就是把上面的longSpaceId以数组的形式存储到新的字段中
@Field(type = FieldType.Keyword) private List<Long> longSpaces;
一定要注意:该字段定义为keyword类型,否则默认就是text类型了
查询就很简单了,传递一个楼栋spaceId的数据,通过terms过滤一把即可
GET face_platform_go_through_record/_search { "size": 50, "query": { "bool": { "must": [ { "match": { "actionType": "1" } }, { "terms": { "longSpaces": [ "1976", "1022" ] } } ] } }, "sort": [ { "recordTime": { "order": "desc" } } ] }
java代码实现:
qb2.must(QueryBuilders.termsQuery("longSpaces", req.getSpaceIds()));
注意:参数2是个List<Long>