Search code examples
javaelasticsearchquery-builderelasticsearch-java-api

ElasticSearch Java Api Query Builder


I'm trying to make a query in ElasticSearch with a defined parameter, but many times it does not work.

There are parameter values ​​that when they have certain characters (as simple as a capital letter) no longer works.

For example, I have 3 registers with key field1 and value hello123, Hello123 and HeLLo-123.

The first works, but the rest always fails.

Can someone help me?

That's my code and the following execution:

    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:

execution result image

P.D: I have observed that the first query that is with parameter hello123 also returns the result of Hello123, this should not be the case ...

Can someone help me?

Thank you

P.D.2 UPDATE

I have tried to create a mapping in the index and then insert the data but it does not work for me. I attach files:

Code:

        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);

The following image is the result of loading url of index (which is called 'snippet'):

localhost:9200/snippet

The result still being the same.

Can someone tell me if I am defining the mapping wrong or am I doing wrong?

Thank you


Solution

  • What's happening is that you are indexing the data without creating an index and specifying the exact mapping that you want.

    Elasticsearch will make assumptions based on the input and it will create one for you. For example, if we index the below:

    POST foo/bar/1
    {
      "key": "HeLLo-123"
    }
    

    We can see that elasticsearch created this:

    {
      "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"
          }
        }
      }
    }
    

    You can see that the field I indexed is specified as a multi-field. The one that you query against is specified as text which is analyzed. The key.keyword field is the one for exact matches (term query). So if you search against the key.keyword field you'll get the results that you expect, better still, create your index and define the mapping as you want it and don't let elasticsearch make any assumptions.