我正在使用Logstash将数据从数据库输入到Elasticsearch。 对于特定的SQL查询,我有一列以CSV格式检索值,例如“ role1; role2; role3”。 该列在Elastic中被作为常规字符串编制索引。
问题: 我需要根据另一个值列表在该字段上进行弹性查询。
例如:在Java端,我有一个值如下的集合:“ role3”,“ role4”,“ role5”,基于此,我应该在Elastic中获取所有匹配的记录“ role3”,“ role4”或“ role5”。
在这种情况下,我的弹性数据如下:
"_source": {
"userName": "user1",
"roles": "role1;role2;role3"
}
"_source": {
"userName": "user2",
"roles": "role7;role8;role9"
}
在这种情况下,它应返回“ user1”的记录,因为它会与“ role3”匹配。
问题: 最好的方法是什么? 我可以使用类似LIKE运算符的查询来查询我的Java列表的所有项目:
//javaList collection has 3 items: "role3", "role4" and "role5"
for (String role: javaList) {
query = QueryBuilders.boolQuery();
query.should(QueryBuilders.wildcardQuery("roles", "*" + role + "*"));
response = client.prepareSearch(indexName).setQuery(query).setTypes(type).execute().actionGet();
hits = response.getHits();
}
然后遍历每个命中,但这听起来像是一个很糟糕的方法,因为javaList可以具有20个iten,这意味着要进行20次查询才能具有弹性。
我需要一种告诉Elastic的方法:
This is my list of roles, query internally and retrieve
only the records that matches at least one of those roles.
为了做到这一点,我理解我无法将该数据索引为String,对吗?理想情况是将其具有数组或类似的内容...
我该如何以最高效的方式做到这一点?
答案 0 :(得分:0)
绝对不应在循环中使用通配符查询。该解决方案最终将表现出较差的性能。
由于roles
字段是常规文本字段,因此Elasticsearch将值“ role1; role2; role3”拆分为单独的标记“ role1”,“ role2”和“ role3”。相同的操作应用于搜索查询。您可以将简单的匹配查询与查询字符串“ role3; role4; role5”结合使用,并由于“ role3”令牌匹配而被点击。
您还可以将roles
字段索引为字符串数组,并且相同的匹配查询仍然有效。