【问题标题】:elasticsearch - Return the tokens of a fieldelasticsearch - 返回字段的标记
【发布时间】:2012-10-22 03:03:33
【问题描述】:

如何在结果中返回特定字段的标记

例如,一个 GET 请求

curl -XGET 'http://localhost:9200/twitter/tweet/1'

返回

{
    "_index" : "twitter",
    "_type" : "tweet",
    "_id" : "1", 
    "_source" : {
        "user" : "kimchy",
        "postDate" : "2009-11-15T14:12:12",
        "message" : "trying out Elastic Search"
    } 
}

我希望将“_source.message”字段的标记包含在结果中

【问题讨论】:

    标签: java search lucene token elasticsearch


    【解决方案1】:

    还有另一种方法可以使用以下 script_fields 脚本:

    curl -H 'Content-Type: application/json' -XPOST 'http://localhost:9200/test-idx/_search?pretty=true' -d '{
        "query" : {
            "match_all" : { }
        },
        "script_fields": {
            "terms" : {
                "script": "doc[field].values",
                "params": {
                    "field": "message"
                }
            }
    
        }
    }'
    

    请务必注意,虽然此脚本返回已编入索引的实际术语,但它还会缓存所有字段值,并且在大索引上可能会使用大量内存。因此,在大型索引上,从存储的字段或源中检索字段值并使用以下 MVEL 脚本即时重新解析它们可能更有用:

    import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
    import java.io.StringReader;
    
    // Cache analyzer for further use
    cachedAnalyzer=(isdef cachedAnalyzer)?cachedAnalyzer:doc.mapperService().documentMapper(doc._type.value).mappers().indexAnalyzer();
    
    terms=[];
    // Get value from Fields Lookup
    //val=_fields[field].values;
    
    // Get value from Source Lookup
    val=_source[field];
    
    if(val != null) {
      tokenStream=cachedAnalyzer.tokenStream(field, new StringReader(val)); 
      CharTermAttribute termAttribute = tokenStream.addAttribute(CharTermAttribute); 
      while(tokenStream.incrementToken()) { 
        terms.add(termAttribute.toString())
      }; 
      tokenStream.close(); 
    } 
    terms
    

    此 MVEL 脚本可以存储为 config/scripts/analyze.mvel 并与以下查询一起使用:

    curl 'http://localhost:9200/test-idx/_search?pretty=true' -d '{
        "query" : {
            "match_all" : { }
        },
        "script_fields": {
            "terms" : {
                "script": "analyze",
                "params": {
                    "field": "message"
                }
            }
        
        }
    }'
    

    【讨论】:

    • 这很可怕,但很有趣。 :) 我希望可以在 DocLookup 中访问 IndexReader(它在那里,但目前是私有的)。这样就可以使用术语向量而不是第二次重新分析文本。
    • 是的,当然。不用脚本也可以通过插件阅读术语向量不是很好吗?
    • @imotov 有什么方法可以从此脚本自动获取字段的正确分析器和字段类型?我想在metacpan.org/module/… 中使用这个功能
    • 请添加tokenStream.reset();在while循环之前(否则我的设置会失败)。
    • 我认为如果不在 elasticsearch 5.0 及更高版本中编写插件,这是不可能实现的。
    【解决方案2】:

    如果您指的是已编入索引的令牌,您可以在消息字段上创建 terms facet。增加size 值以获取更多条目,或设置为0 以获取所有术语。

    Lucene 提供了存储术语向量的功能,但目前无法通过 elasticsearch 访问它(据我所知)。

    你为什么需要它?如果您只想检查索引的内容,可以查看analyze api

    【讨论】:

    • 很好,这就是我要找的。谢谢
    猜你喜欢
    • 2012-07-03
    • 2015-06-11
    • 2011-09-10
    • 2017-01-17
    • 1970-01-01
    • 2012-03-25
    • 2018-06-13
    • 1970-01-01
    • 2019-11-30
    相关资源
    最近更新 更多