Elasticsearch:从文档中检索长文本字段

时间:2019-08-30 11:28:41

标签: java elasticsearch

我有一个在ES中建立索引的文档。该文档具有3个文本字段F1F2F3

当我尝试使用Java API搜索该文档时,我只有字段F1F2的值,而字段F3却显示为空。

QueryBuilder query =  //Some query

SearchResponse response = client.prepareSearch(index)
                .addDocValueField("F1.keyword")
                .addDocValueField("F2.keyword")
                .addDocValueField("F3.keyword")
                .setQuery(query)
                .execute()
                .actionGet();

SearchHit hit = response.getHits().getAt(0);

System.out.println("F1 : "+hit.getField("F1.keyword").getValue());
System.out.println("F2 : "+hit.getField("F2.keyword").getValue());
System.out.println("F3 : "+hit.getField("F3.keyword").getValue()); // empty

我的字段F3可能很长。在我用于测试的文档中,它的字符数大于300,并且可能更长。

我的索引映射是:

"mappings": {
      "MyIndex": {
        "properties": {
          "F1": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "F2": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "F3": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }

所以我将ignore_above的映射中的F3字段更新为20000(可能是个坏主意?),但是我仍然有相同的行为。

问题是什么,正确的方法是什么?

注意:

  • 使用ES 5.6.3
  • 我无需在字段F3上进行任何分析/术语搜索,只需在查询匹配F1F2时检索其值。
  • 我将收到少量此类文档,因此效率不会成为大问题

编辑:

奇怪的是,当我用带有查询的浏览器请求elasticsearch时,我得到了预期的结果:

http://localhost:9200/MyIndex/_search?pretty=true?{"query": {"match_all": {}}}

1 个答案:

答案 0 :(得分:1)

在Elasticsearch中,默认行为将文本字符串映射为两种不同的Elasticsearch类型:textkeyword。它们是不同的东西,用于不同的目的,主要是text是全文搜索字段,而keyword就像结构化常量值。在the docs

中了解更多信息

对于您而言,默认包含keyword字段似乎没有帮助。在查询中,您只需获取“常规” F3字段和/或F1F2的常规字段即可。

最后,我对ES Java客户端不是很熟悉,但是如果您想进行源过滤(即,仅从请求中获取值的子集),那么我不认为addDocValueField()是对。检出:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/5.6/java-rest-high-search.html#_source_filtering