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 analyzedkey.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();

希望对您有所帮助