ElasticSearch Java Api 查询生成器
ElasticSearch Java Api Query Builder
我正在尝试使用定义的参数在 ElasticSearch 中进行查询,但很多时候都不起作用。
有一些参数值,当它们具有某些字符(像大写字母一样简单)时不再有效。
例如,我有 3 个寄存器,键为 field1,值为 hello123、Hello123 和 HeLLo-123。
第一个有效,但其余的总是失败。
有人可以帮助我吗?
这是我的代码和下面的执行:
logger.info("Testing queries");
TransportClient client = elasticSearchManager.getClient();
String[] values = {"hello123","Hello123","HeLLo-123"};
for (int i = 0; i < 3; i++) {
XContentBuilder jsonInsert = jsonBuilder().startObject();
jsonInsert.field("field1", values[i]);
jsonInsert.endObject();
IndexResponse responseDB = client.prepareIndex(index, "id").setSource(jsonInsert).get();
logger.info("response with value : "+values[i]+" => " + responseDB.getResult());
logger.info("*********************************************");
}
logger.info("VALUES INSERTED");
logger.info("***************");
logger.info("QUERIES");
for (int i = 0; i < 3; i++){
BoolQueryBuilder query = QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("field1", values[i]));
SearchResponse response = client.prepareSearch(WIFI4EUOPConstants.indexSnippet).setQuery(query).get();
logger.info("field with value "+values[i]+" : ");
logger.info(response.toString());
logger.info("*********************************************");
}
执行:
execution result image
P.D: 我观察到第一个带参数 hello123 的查询也是 returns Hello123 的结果,这不应该是这样的...
有人可以帮助我吗?
谢谢
P.D.2 更新
我试过在索引中创建一个映射,然后插入数据,但它对我不起作用。我附上文件:
代码:
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("properties")
.startObject("field1").field("type", "string").field("analyzer", "keyword").endObject()
.endObject().endObject();
client.admin().indices().prepareCreate(index).addMapping("id",mapping);
下图是加载索引url的结果(调用'snippet'):
结果还是一样
谁能告诉我是我定义的映射有误还是我做错了?
谢谢
发生的事情是您在没有创建索引并指定您想要的确切 mapping 的情况下为数据编制索引。
Elasticsearch 会根据输入做出假设,并为您创建一个假设。例如,如果我们索引以下内容:
POST foo/bar/1
{
"key": "HeLLo-123"
}
我们可以看到 elasticsearch 创建了这个:
{
"foo": {
"aliases": {},
"mappings": {
"bar": {
"properties": {
"key": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
},
"settings": {
"index": {
"creation_date": "1517863731064",
"number_of_shards": "5",
"number_of_replicas": "1",
"uuid": "iQzvEfU0Sli3c2LRC6gjyA",
"version": {
"created": "5030199"
},
"provided_name": "foo"
}
}
}
}
可以看到我索引的字段指定为multi-field. The one that you query against is specified as text
which is analyzed。 key.keyword
字段用于精确匹配(术语查询)。因此,如果您搜索 key.keyword
字段,您将获得预期的结果,更好的是,创建索引并根据需要定义映射,不要让 elasticsearch 做出任何假设。
好吧,最后在 alkis 的帮助下,我有了以下解决方案:
String sourcedef = "{\n" +
" \"id\" : {\n" +
" \"properties\" : { \n" +
" \"field1\" : { \"type\":\"keyword\"}\n" +
" } \n" +
" }\n" +
" }\n" +
" }\n" +
"}";
// Convert String to Map<String, Object>
Map<String, Object> source = Utils.fromJSON(sourcedef);
String type = "id";
String indexDefined = "newindex";
CreateIndexResponse response = client.admin().indices().prepareCreate(indexDefined).addMapping(type,source).execute().actionGet();
使用前面的代码,我们创建了一个带映射的索引。我们定义字段 'field1' 将是关键字类型,这将与我们输入的查询完全匹配。
然后,当我们使用 termQuery 执行以下代码时,它可以正常工作并很好地过滤结果:
BoolQueryBuilder query = QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("field1", "definedvalue"));
SearchResponse response = client.prepareSearch(indexDefined).setQuery(query).get();
希望对您有所帮助
我正在尝试使用定义的参数在 ElasticSearch 中进行查询,但很多时候都不起作用。
有一些参数值,当它们具有某些字符(像大写字母一样简单)时不再有效。
例如,我有 3 个寄存器,键为 field1,值为 hello123、Hello123 和 HeLLo-123。
第一个有效,但其余的总是失败。
有人可以帮助我吗?
这是我的代码和下面的执行:
logger.info("Testing queries");
TransportClient client = elasticSearchManager.getClient();
String[] values = {"hello123","Hello123","HeLLo-123"};
for (int i = 0; i < 3; i++) {
XContentBuilder jsonInsert = jsonBuilder().startObject();
jsonInsert.field("field1", values[i]);
jsonInsert.endObject();
IndexResponse responseDB = client.prepareIndex(index, "id").setSource(jsonInsert).get();
logger.info("response with value : "+values[i]+" => " + responseDB.getResult());
logger.info("*********************************************");
}
logger.info("VALUES INSERTED");
logger.info("***************");
logger.info("QUERIES");
for (int i = 0; i < 3; i++){
BoolQueryBuilder query = QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("field1", values[i]));
SearchResponse response = client.prepareSearch(WIFI4EUOPConstants.indexSnippet).setQuery(query).get();
logger.info("field with value "+values[i]+" : ");
logger.info(response.toString());
logger.info("*********************************************");
}
执行:
execution result image
P.D: 我观察到第一个带参数 hello123 的查询也是 returns Hello123 的结果,这不应该是这样的...
有人可以帮助我吗?
谢谢
P.D.2 更新
我试过在索引中创建一个映射,然后插入数据,但它对我不起作用。我附上文件:
代码:
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("properties")
.startObject("field1").field("type", "string").field("analyzer", "keyword").endObject()
.endObject().endObject();
client.admin().indices().prepareCreate(index).addMapping("id",mapping);
下图是加载索引url的结果(调用'snippet'):
结果还是一样
谁能告诉我是我定义的映射有误还是我做错了?
谢谢
发生的事情是您在没有创建索引并指定您想要的确切 mapping 的情况下为数据编制索引。
Elasticsearch 会根据输入做出假设,并为您创建一个假设。例如,如果我们索引以下内容:
POST foo/bar/1
{
"key": "HeLLo-123"
}
我们可以看到 elasticsearch 创建了这个:
{
"foo": {
"aliases": {},
"mappings": {
"bar": {
"properties": {
"key": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
},
"settings": {
"index": {
"creation_date": "1517863731064",
"number_of_shards": "5",
"number_of_replicas": "1",
"uuid": "iQzvEfU0Sli3c2LRC6gjyA",
"version": {
"created": "5030199"
},
"provided_name": "foo"
}
}
}
}
可以看到我索引的字段指定为multi-field. The one that you query against is specified as text
which is analyzed。 key.keyword
字段用于精确匹配(术语查询)。因此,如果您搜索 key.keyword
字段,您将获得预期的结果,更好的是,创建索引并根据需要定义映射,不要让 elasticsearch 做出任何假设。
好吧,最后在 alkis 的帮助下,我有了以下解决方案:
String sourcedef = "{\n" +
" \"id\" : {\n" +
" \"properties\" : { \n" +
" \"field1\" : { \"type\":\"keyword\"}\n" +
" } \n" +
" }\n" +
" }\n" +
" }\n" +
"}";
// Convert String to Map<String, Object>
Map<String, Object> source = Utils.fromJSON(sourcedef);
String type = "id";
String indexDefined = "newindex";
CreateIndexResponse response = client.admin().indices().prepareCreate(indexDefined).addMapping(type,source).execute().actionGet();
使用前面的代码,我们创建了一个带映射的索引。我们定义字段 'field1' 将是关键字类型,这将与我们输入的查询完全匹配。
然后,当我们使用 termQuery 执行以下代码时,它可以正常工作并很好地过滤结果:
BoolQueryBuilder query = QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("field1", "definedvalue"));
SearchResponse response = client.prepareSearch(indexDefined).setQuery(query).get();
希望对您有所帮助