业务场景一:有两个父子type,store(父type)和relation(子type),其中store主键为storeId,relation存储了orgId与storeId的关联,输入为两个orgId,要求输出与这两个orgId都关联的store信息。
cbs_chnl_store
{
"properties": {
"storeId": {
"type": "string"
},
"storeName": {
"type": "string"
},
"telphone": {
"type": "string"
}
}
}
cbs_orgdealer_relation
{
"_parent": {
"type": "cbs_chnl_store"
},
"_routing": {
"required": true
},
"properties": {
"storeId": {
"type": "string"
},
"orgId": {
"type": "string"
},
"isDelete": {
"type": "integer"
}
}
}
DSL:
GET cbs_chnl_store/_search
{
"query": {
"bool": {
"must": {
"has_child": {
"type": "cbs_orgdealer_relation",
"query": {
"bool": {
"must": [
{
"terms": {
"orgId": [
"ecf25bd6a1a34a99829e648b0e6775f1"
]
}
},
{
"match": {
"isDelete": 0
}
}
]
}
}
}
},
"must": {
"has_child": {
"type": "cbs_orgdealer_relation",
"query": {
"bool": {
"must": [
{
"terms": {
"orgId": [
"aebcd333a30b4d098bc34719c211728d"
]
}
},
{
"match": {
"isDelete": 0
}
}
]
}
}
}
}
}
}
}
业务场景二:只有一个relation关联表,给定两个orgId,求出relation表中与这两个orgId都存在关联的storeId记录。
这个问题在国内的论坛上没有找到答案(甚至都没有人讨论,捂脸),最后终于在stackoverflow上找到了答案(不得不感慨,国内的技术气氛还是太浮躁啦),采用的是桶聚合的思路,原文地址:https://stackoverflow.com/questions/42943980/elasticsearch-query-to-find-intersection-of-two-queries
DSL:
GET cbs_orgdealer_relation/_search
{
"size": 0,
"query": {
"bool": {
"filter": {
"terms": {
"orgId":["a", "c"]
}
}
}
},
"aggs": {
"user_ids": {
"terms": {
"field": "storeId"
},
"aggs": {
"orgs_card": {
"cardinality": {
"field": "orgId"
}
},
"state_filter": {
"bucket_selector": {
"buckets_path": {
"orgsCard": "orgs_card"
},
"script": "orgsCard == 2"
}
}
}
}
}
}
拓展思考:场景二中的情景,如果不用桶聚合的话,不知道能否用Hadoop(MR)或者转换表结构的思路去实现呢?这一块暂时没有深入去研究,后面有机会再验证吧。