简体   繁体   中英

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

PD: 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

PD2 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'):

本地主机:9200/片段

The result still being the same.

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

Thank you

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM