Elasticsearch - 使用“关键字”类型搜索不起作用

时间:2018-02-01 15:20:44

标签: java elasticsearch

我使用Elasticsearch Java rest client 6.1。当我尝试通过一些参数找到日志而不是在一个字段中时,我什么也得不到。

这是我的代码:

 @Override
    public SearchResponse findLogsByValues(ElasticSearchLogRequest esLogRequest, Pageable pageable) {
        SearchRequest searchRequest = new SearchRequest("portal-logs-*");

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder bqb = QueryBuilders.boolQuery();
 if (esLogRequest.getLevels() != null) {
            Iterator<String> iterator = esLogRequest.getLevels().iterator();
            int counter = 0;
            SpanOrQueryBuilder spanOrQueryBuilder = null;
            while (iterator.hasNext()) {
                if (counter == 0) {
                    spanOrQueryBuilder = new SpanOrQueryBuilder(QueryBuilders.
                            spanTermQuery("level", iterator.next().toLowerCase()));
                } else {
                    spanOrQueryBuilder.addClause(QueryBuilders.
                            spanTermQuery("level", iterator.next().toLowerCase()));
                }
                counter++;
            }
            bqb.filter(spanOrQueryBuilder);
        }
 try {
            searchResponse = client.search(searchRequest);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return searchResponse;
    }

这是我的json请求:

{

    "levels": ["TRACE","INFO"]

}

以下是ES中对象(对象)的外观:

{
    "code": 200,
    "error": "",
    "message": "",
    "data": {
        "content": [
                    {
                    "level": "INFO",
                    "module": "test module",
                    "ip": "192.168.3.93",
                    "thread": "test thread",
                    "sessionId": "1",
                    "office": "1",
                    "message": "test message 3",
                    "userName": "user",
                    "timeStamp": "2018-01-25T08:02:50.000Z",
                    "userLogin": "user",
                    "node": "first node",
                    "system": "super system 1",
                    "port": 9300,
                    "header": "test Header",
                    "submodule": "test submodule",
                    "location": {
                        "lon": -71.34,
                        "lat": 41.12
                    },
                    "operation": "some operation",
                    "device": "some device"
        }
        ],
        "totalPages": 1,
        "last": true,
        "totalElements": 0,
        "size": 0,
        "number": 0,
        "sort": null,
        "first": true,
        "numberOfElements": 0
    }
}

这是我的映射模板:

  PUT _template/portal-logs
{
  "template": "portal-logs-*",
  "settings": { "number_of_shards": 5 },
  "mappings": {
      "logs_info": {
        "_all": {
          "enabled": false
        },
        "properties": {
          "device": {"type": "keyword"},
          "header": {"type": "text"},
          "ip": {"type": "keyword"},
          "level": {"type": "keyword"},
          "location": {"type": "geo_point"},
          "message": {"type": "text"},
          "module": {"type": "keyword"},
          "node": {"type": "keyword"},
          "office": {"type": "keyword"},
          "operation": {"type": "keyword"},
          "port": {"type": "integer"},
          "sessionId": {"type": "keyword"},
          "submodule": {"type": "keyword"},
          "system": {"type": "keyword"},
          "thread": {"type": "keyword"},
          "timeStamp": {"type": "date"},
          "userLogin": {"type": "keyword"},
          "userName": {"type": "keyword"}
        }
      }
    }
  }

所以当在映射字段“level”并将其设置为“text”时 - 它工作正常但是当我设置“keyword”时 - 我收到一个空的json。 我需要字段“level”有一个严格的类型“关键字”,当我想获得所有具有“level”“INFO”或“TRACE”的日志时它必须工作。 在这种情况下我该怎么办?为什么使用关键字它不起作用?

1 个答案:

答案 0 :(得分:0)

使用text类型,您的字段将不会被分析,并且需要与您的搜索字词完全匹配,包括区分大小写。如果将字段类型设置为GET _search { "query": { "terms": { "level": [ "INFO", "TRACE" ] } } } ,则会对其进行分析,在默认分析器下,将使搜索大小写不敏感。

此外,除非您的关卡字段包含多个术语,否则您应该能够使用TermsQuery搜索多个值。例如(以DSL格式):

let dataStack: DataStack = {
    let dataStack = DataStack(xcodeModelName: "ModelName")
    do {
        try dataStack.addStorageAndWait(SQLiteStore(fileURL: storagePathUrl, configuration: "Default", localStorageOptions: .
            recreateStoreOnModelMismatch))
    } catch let error {
        print("Cannot set up database storage: \(error)")
    }
    return dataStack
}()