# 高级文本评分脚本

> 警告 本页面上所描述的功能被认为是实验性的、并且在未来的版本可被修改或删除

文本特征，譬如在脚本中通过访问`_index`变量来获取某一个指定词条的词频或文档频率。 它有可能被用在像这样的场景中，你想通过一个脚本在[function\_core查询](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html)中来实现一个自己的评分模块。在每个分片中统计文档集合，而不是每个索引。

## 名词解释

|  名词 | 解释                                            |
| :-: | --------------------------------------------- |
|  df | 文档频率。词条在多少个文档中出现。按文档的每个字段计算。                  |
|  tf | 词频。词条在指定的文档中出现的次数。                            |
| ttf | 总词频。词条出现在所有文档中的次数，也就是`tf`在所有文档中的和。按文档的每个字段计算。 |

`df`和`ttf`按每个分片计算，因此这些数字会跟随分片中的当前文档一起变化。

## 分片统计

\_index.numDocs()

  _分片中文档数_

\_index.maxDoc()

  _分片中最高的文档数_

\_index.numDeletedDocs()

  _分片中删除的文档数_

## 字段统计

字段统计可以通过下标运算这样访问：`_index['FIELD']`.

\_index\['FIELD'].docCount()

  _含有 **FIELD** 字段的文档数。不包含已删除的文档。_

\_index\['FIELD'].sumttf()

   _**FIELD** 字段的所有词条的词频总和。_

\_index\['FIELD'].sumdf()

   _**FIELD** 字段的所有词条的文档频率和_

字段统计按每个分片计算，因此这些数字会跟随分片中的当前文档一起变化。在一个字段中词条的数量不能通过`_index`变量访问，请参考[Token count datatype](https://www.elastic.co/guide/en/elasticsearch/reference/current/token-count.html)章节解决。

## 词条统计

一个字段的词条统计可以通过下标运算这样访问：`_index['FIELD']['TERM']`。这将永远不会返回`null`，即使词条或字段不存在。如果你不需要词频，调用`_index['FIELD'].get('TERM', 0)` 避免不必要的频率计算。该标志将只影响你的文档设置[index\_options](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-options.html)。

\_index\['FIELD']\['TERM'].df()

   _**FIELD**字段中**TERM**词条的文档频率。即使词条不存在文档中不存在也会有返回_

\_index\['FIELD']\['TERM'].ttf()

   _**FIELD**字段中\*TER&#x4D;_&#x8BCD;条的总词频。即使词条不存在文档中不存在也会有返回。

\_index\['FIELD']\['TERM'].tf()

   _**FIELD**字段中\*TER&#x4D;_&#x8BCD;条的词频。如果词条不存在于文档中，将返回0。

## 词条位置（positions），偏移（offsets）和有效载荷（payloads）

如果您需要获取一个词条在字段中的位置信息，可以调用`_index['FIELD'].get('TERM', flag)`来获取，`flag`可以是如下取值：

|             |                |
| ----------- | -------------- |
| \_POSITIONS | 如果你需要这个词条的位置   |
| \_OFFSETS   | 如果你需要这个词条的偏移   |
| \_PAYLOADS  | 如果你需要这个词条的有效载荷 |
| \_CACHE     | 如果你需要遍历所有位置好几次 |

迭代器使用底层的Lucene类遍历位置。出于效率的考虑，您只能遍历一次位置信息。如果您需要反复获取位置信息，可以设置`_CACHE`标志。

如果你需要获取多个信息，你可以用使用运算符`|`。例如，以下将返回一个对象的位置和有效载荷，以及所有的统计数据：

```javascript
_index['FIELD'].get('TERM', _POSITIONS | _PAYLOADS)
```

可以遍历返回的集合，通过一个`POS_OBJECT`对象来获取每个词条的位置、偏移量、有效载荷信息。

POS\_OBJECT.position

  _词条的位置。_

POS\_OBJECT.startOffset

  _词条开始的偏移量。_

POS\_OBJECT.endOffset

  _词条结束的偏移量。_

POS\_OBJECT.payload

  _词条的有效载荷。_

POS\_OBJECT.payloadAsInt(missingValue)

  _转换为整数的词条有效载荷。如果当前位置没有有效载荷时，**missingValue**将被返回。只能在你明确知道有效载荷为整数类型时才能调用此方法。_

POS\_OBJECT.payloadAsFloat(missingValue)

  _转换为浮点数的词条有效载荷。如果当前位置没有有效载荷时，**missingValue**将被返回。只能在你明确知道有效载荷为浮点类型时才能调用此方法。_

POS\_OBJECT.payloadAsString()

  _转换成字符串的词条有效载荷。如果当前位置没有有效载荷，`null`将被退回。只能在你明确知道有效载荷为字符串类型时才能调用此方法。_

例如，获取词条`foo`的有效载荷的总数：

```javascript
termInfo = _index['my_field'].get('foo',_PAYLOADS);
score = 0;
for (pos in termInfo) {
    score = score + pos.payloadAsInt(0);
}
return score;
```

## 词条向量：

`_index`变量只能被用于收集单一词条的统计数据。如果您想获取整个字段的所有词条信息，您必须先保存词条向量（参见[term\_vector](https://www.elastic.co/guide/en/elasticsearch/reference/current/term-vector.html)）。要访问它们，请调用`_index.termVectors()`得到[字段](https://lucene.apache.org/core/4_0_0/core/org/apache/lucene/index/Fields.html)实例, 你可以参见[lucene文档](https://lucene.apache.org/core/4_0_0/core/org/apache/lucene/index/Fields.html)来遍历这个集合，来获取每个词条在字段中的信息。如果词条向量没有被存储此方法将返回null。
