如何在Java API中使用Analyzer和两个参数执行弹性搜索术语查询

时间:2016-03-27 21:09:27

标签: spring elasticsearch java-api

我是Elastic Search的新手,我正在将它与MongoDB集成以索引和搜索数据。

所有这些都运行正常,我使用以下示例构建索引:

    curl -XPUT localhost:9200/test/newperson/1 -d '{
  "type": "mongodb",
  "mongodb": {
    "servers": [
      { "host": "pc-4372", "port": 27017 }
    ],
    "db": "newPerson",
    "collection": "Person",
    "options": { "secondary_read_preference": true },
    "gridfs": false
   },
  "index": {
    "name": "mongoIndex",
    "type": "Person"
  }
}'

我目前正在构建一个使用Java API来执行所需搜索查询的Web服务。

我需要在构建的索引中搜索两个相同的值" term query"。我知道对于术语查询,我们需要使用分析器来分析文本并能够检索相同的值。

我已经尝试了几种方法来构建索引并为某些字段指定分析器,但我无法做到。此外,我试图从Java API级别开始,它工作正常,但只有一个字段,我无法用两个字段做到这一点。

 SearchResponse r1 = client.prepareSearch("rootcause")
                    .setQuery(QueryBuilders.queryString("_id:" + rc.getRootCause_ID()).analyzer("snowball"))
                    .execute() 
                    .actionGet();

我正在构建一个原型来诊断某些设备故障,

我想按设备型号和用户输入的症状进行搜索。我也试过以下代码:

    SearchResponse response = client.prepareSearch("modelsymptom")
            .setQuery(QueryBuilders.queryString("model_id: " + "MO-1" + " AND " + "symptom: RC-4").analyzer("snowball"))
            .execute()
            .actionGet();

上述查询的检索结果包含RC-4或MO-1的所有文档以及其他不正确的文档。此查询应仅检索一个结果。

更好的是,使用规定的分析器构建索引还是从Java API级别创建索引?

根据我的理解,我认为用指数构建分析器肯定会更好,但我不知道到目前为止。

2 个答案:

答案 0 :(得分:1)

您不需要任何特殊的分析器,只需使用“必须”和两个术语的bool查询。并且“简单查询”主要用于手动测试查询,我不会在代码中使用它。也总是首先使用REST API尝试查询。

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "model": "XXXX",
          }
        },
        {
          "term": {
            "symptom": "YYYY" 
          }
        }
      ]
    }
  }
}

答案 1 :(得分:1)

  

我知道对于学期查询,我们需要使用分析器来分析文本   并能够检索相同的值。

这是不正确的。

虽然全文查询将在执行之前分析查询字符串,但是术语级查询将根据存储在倒排索引中的确切术语进行操作。

查询全文字段时,请改用匹配查询,该查询了解字段的分析方式。

否则您将遇到此处描述的问题: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html

  

更好的是,用规定的分析仪建立索引或做   它来自Java API级别?

无论哪种方式,都取决于您的具体情况。

如果需要,可以使用Java中的分析器创建索引。

String analyser = "{...}";

CreateIndexRequestBuilder createIndexRequestBuilder = 
    client.admin().indices().prepareCreate("indexName");
createIndexRequestBuilder.setSettings(analyser);
createIndexRequestBuilder.execute().actionGet();

您的分析仪类似于:

{
    "analysis": 
    {    
        "analyzer": 
        {
            "my_analiser": 
            {
                "type": "english"
            }
        }
    }
}

但是,您需要创建自己的自定义映射并在那里指定分析器。

如果您没有指定自己的映射,当Elasticsearch在文档中检测到新的字符串字段时,它会自动将其配置为全文字符串字段并使用标准分析器对其进行分析。这对你来说已经足够了,但通常它不是,你需要建立自己的映射。你也可以用Java做到这一点。

// Index (and mapping) do not exist
CreateIndexRequestBuilder createIndexRequestBuilder = 
  client.admin().indices().prepareCreate("indexName");
createIndexRequestBuilder.addMapping("typeName", mapping);
response = createIndexRequestBuilder.execute().actionGet();

// Index exists but not mapping
PutMappingRequestBuilder preparePutMappingBuilder = 
  client.admin().indices().preparePutMapping("indexName");
preparePutMappingBuilder.setSource(mapping).setType("typeName");
response = preparePutMappingBuilder.execute().actionGet();
  

如何使用Analyzer和Two进行弹性搜索术语查询   Java API中的参数

您可以使用复合查询(如布尔查询:

)组合两个术语查询

或者使用条款查询:

但是根据你在这里描述的内容,如果你真的需要使用分析文本,你更可能需要多匹配查询,或者需要两个匹配查询的布尔查询。

MultiMatchQueryBuilder queryBuilder = 
   new MultiMatchQueryBuilder("foo", "fieldOne", "fieldTwo");
client.prepareSearch()
     .setIndices(index)
     .setQuery(queryBuilder)
     .execute().actionGet();

或者:

QueryBuilder firstQueryBuilder = QueryBuilders.matchQuery("fieldOne", "foo");
QueryBuilder secondQueryBuilder = QueryBuilders.matchQuery("fieldTwo", "foo");
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(firstQueryBuilder);
boolQueryBuilder.must(secondQueryBuilder);
client.prepareSearch()
     .setIndices(index)
     .setQuery(queryBuilder)
     .execute().actionGet();

希望这有帮助。