问题描述 请教一个es问题,tag字段有三种已知类型java,css,html,一条数据可以包含多个tag;那么如何检索出包含其他未知tag的数据,例如[java,php],[html, javascript]
提供一种纯Elasticsearch的方法,当然已知类型过多的情况下应该就不太适用了。但是算是一种方法吧。就是增加一个tag数量的计数器字段cnt。你描述的场景就可以实现了。下面是我做的Demo1、先插入数据 PUT _bulk {"index": {"_index": "test_index", "_id": "1"}} {"cnt": 1, "tags": ["java"]} {"index": {"_index": "test_index", "_id": "2"}} {"cnt": 1, "tags": ["css"]} {"index": {"_index": "test_index", "_id": "3"}} {"cnt": 1, "tags": ["html"]} {"index": {"_index": "test_index", "_id": "4"}} {"cnt": 2, "tags": ["java","css"]} {"index": {"_index": "test_index", "_id": "5"}} {"cnt": 2, "tags": ["java","html"]} {"index": {"_index": "test_index", "_id": "6"}} {"cnt": 2, "tags": ["css","html"]} {"index": {"_index": "test_index", "_id": "7"}} {"cnt": 3, "tags": ["java", "css", "html"]} {"index": {"_index": "test_index", "_id": "8"}} {"cnt": 2, "tags": ["java","php"]} {"index": {"_index": "test_index", "_id": "9"}} {"cnt": 2, "tags": ["html","javascript"]} 2、查询 GET /test_index/_search { "query": { "bool": { "must_not": [ { "bool": { "must": [ { "term": { "cnt": { "value": 1 } } }, { "match": { "tags": "java" } } ] } }, { "bool": { "must": [ { "term": { "cnt": { "value": 1 } } }, { "match": { "tags": "css" } } ] } }, { "bool": { "must": [ { "term": { "cnt": { "value": 1 } } }, { "match": { "tags": "html" } } ] } }, { "bool": { "must": [ { "term": { "cnt": { "value": 2 } } }, { "match": { "tags": { "query": "java css", "minimum_should_match": 2 } } } ] } }, { "bool": { "must": [ { "term": { "cnt": { "value": 2 } } }, { "match": { "tags": { "query": "java html", "minimum_should_match": 2 } } } ] } }, { "bool": { "must": [ { "term": { "cnt": { "value": 2 } } }, { "match": { "tags": { "query": "css html", "minimum_should_match": 2 } } } ] } }, { "bool": { "must": [ { "term": { "cnt": { "value": 3 } } }, { "match": { "tags": { "query": "java css html", "minimum_should_match": 3 } } } ] } } ] } } } 结果如下: { "took" : 4, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 2, "relation" : "eq" }, "max_score" : 0.0, "hits" : [ { "_index" : "test_index", "_type" : "_doc", "_id" : "8", "_score" : 0.0, "_source" : { "cnt" : 2, "tags" : [ "java", "php" ] } }, { "_index" : "test_index", "_type" : "_doc", "_id" : "9", "_score" : 0.0, "_source" : { "cnt" : 2, "tags" : [ "html", "javascript" ] } } ] } } 当然这个肯定是不通用的,比如已知类型过多,组合的方式就会变得过多,查询语句就会变得超级复杂。要做成通用的,可以在逻辑上进行处理,适用scroll遍历数据,然后在逻辑上判断,查出来的tags是否是已知类型集合的子集即可
提供一种纯Elasticsearch的方法,当然已知类型过多的情况下应该就不太适用了。但是算是一种方法吧。就是增加一个tag数量的计数器字段cnt。你描述的场景就可以实现了。
下面是我做的Demo
1、先插入数据
2、查询
结果如下:
当然这个肯定是不通用的,比如已知类型过多,组合的方式就会变得过多,查询语句就会变得超级复杂。
要做成通用的,可以在逻辑上进行处理,适用scroll遍历数据,然后在逻辑上判断,查出来的tags是否是已知类型集合的子集即可