1

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

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your quick response. I have tried to create a mapping and then repeat the code but it still gives me the same problems, I do an update in the post so you can see the modifications.
Did you delete the previous index? Delete it first and then create it. Moreover, why are using string type? If you want the input to be analyzed then use text with an analyzer, if not (exact match search, even the casing) then use type keyword
I've deleted the previous index. Now i've changed code to this but still not working: XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("properties") .startObject("field1").field("type", "text").field("analyzer", "keyword").endObject() .endObject().endObject(); I've already changed type to text, but still not working Thanks
I've lost you. You mention in your update question that the mapping is the one you posted. That's the mapping that will be created if you do nothing and it does exactly what I've described in my answer. If you have a new mapping please update your question. Moreover provide the input and the expected output. e.g. you want to be case insensitive or what not
Thanks for your help, i've added the type keyword and it's working now.
|
0

Well, finally with the help of alkis I have the following solution:

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

With the previous code we create an index with mapping. We are defining that the field 'field1' will be of keyword type, which will make an exact match of the query that we put.

Then, when we execute the following code with a termQuery, it works and filters the results well:

BoolQueryBuilder query = QueryBuilders.boolQuery()
                .filter(QueryBuilders.termQuery("field1", "definedvalue"));
SearchResponse response = client.prepareSearch(indexDefined).setQuery(query).get();

Hope it helps

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.