根据值列表获取Elasticsearch匹配项

时间:2018-09-03 14:56:25

标签: java elasticsearch logstash

我正在使用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,对吗?理想情况是将其具有数组或类似的内容...

我该如何以最高效的方式做到这一点?

1 个答案:

答案 0 :(得分:0)

绝对不应在循环中使用通配符查询。该解决方案最终将表现出较差的性能。

由于roles字段是常规文本字段,因此Elasticsearch将值“ role1; role2; role3”拆分为单独的标记“ role1”,“ role2”和“ role3”。相同的操作应用于搜索查询。您可以将简单的匹配查询与查询字符串“ role3; role4; role5”结合使用,并由于“ role3”令牌匹配而被点击。

您还可以将roles字段索引为字符串数组,并且相同的匹配查询仍然有效。

相关问题