简体   繁体   English

ElasticSearch 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.我正在尝试使用定义的参数在 ElasticSearch 中进行查询,但很多时候它不起作用。

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.例如,我有 3 个寄存器,键为 field1,值为 hello123、Hello123 和 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 ... PD:我观察到带有参数 hello123 的第一个查询也返回了 Hello123 的结果,这不应该是这种情况......

Can someone help me?有人能帮我吗?

Thank you谢谢

PD2 UPDATE PD2 更新

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'):下图是加载索引url的结果(称为'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. Elasticsearch 将根据输入做出假设,并为您创建一个假设。 For example, if we index the below:例如,如果我们索引以下内容:

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

We can see that elasticsearch created this:我们可以看到 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"
      }
    }
  }
}

You can see that the field I indexed is specified as a multi-field .可以看到我索引的字段被指定为multi-field The one that you query against is specified as text which is analyzed .您查询的那个被指定为被分析的text The key.keyword field is the one for exact matches (term query). key.keyword字段用于精确匹配(术语查询)。 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.因此,如果您针对key.keyword字段进行搜索,您将获得您期望的结果,更好的是,创建您的索引并根据需要定义映射,不要让 elasticsearch 做出任何假设。

Well, finally with the help of alkis I have the following solution:好吧,最后在 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();

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.我们定义了字段 'field1' 将是关键字类型,这将使​​我们输入的查询完全匹配。

Then, when we execute the following code with a termQuery, it works and filters the results well:然后,当我们使用 termQuery 执行以下代码时,它可以很好地过滤结果:

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

Hope it helps希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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