Elasticsearch:来自给定文档集的总术语频率和doc计数

时间:2018-01-11 07:30:17

标签: elasticsearch term-vectors

我试图从给定的文档集中获取总术语频率和文档计数,但elasticsearch中的_termvectors从索引中的所有文档返回ttf和doc_count。是否有任何方法可以指定文档列表(文档ID),以便结果仅基于这些文档。

以下是文档详细信息和查询以获得总学期频率:

索引详情:

PUT /twitter
{ "mappings": {
    "tweets": {
      "properties": {
        "name": {
          "type": "text",
          "analyzer":"english"
        }
      }
    }
  },
  "settings" : {
    "index" : {
      "number_of_shards" : 1,
      "number_of_replicas" : 0
    }
  }
}

文档详细信息:

PUT /twitter/tweets/1
{
  "name":"Hello bar"
}

PUT /twitter/tweets/2
{
  "name":"Hello foo"
}

PUT /twitter/tweets/3
{
  "name":"Hello foo bar"
}

它会创建三个带有ID 1,2和3的文档。现在假设带有ID 1和2的推文属于user1,3个属于另一个用户,我想获得user1的termvectors。

查询以获得此结果:

GET /twitter/tweets/_mtermvectors
{
  "ids" : ["1", "2"],
  "parameters": {
      "fields": ["name"],
      "term_statistics": true,
      "offsets":false,
      "payloads":false,
      "positions":false
  }
}

响应:

    {
  "docs": [
    {
      "_index": "twitter",
      "_type": "tweets",
      "_id": "1",
      "_version": 1,
      "found": true,
      "took": 1,
      "term_vectors": {
        "name": {
          "field_statistics": {
            "sum_doc_freq": 7,
            "doc_count": 3,
            "sum_ttf": 7
          },
          "terms": {
            "bar": {
              "doc_freq": 2,
              "ttf": 2,
              "term_freq": 1
            },
            "hello": {
              "doc_freq": 3,
              "ttf": 3,
              "term_freq": 1
            }
          }
        }
      }
    },
    {
      "_index": "twitter",
      "_type": "tweets",
      "_id": "2",
      "_version": 1,
      "found": true,
      "took": 1,
      "term_vectors": {
        "name": {
          "field_statistics": {
            "sum_doc_freq": 7,
            "doc_count": 3,
            "sum_ttf": 7
          },
          "terms": {
            "foo": {
              "doc_freq": 2,
              "ttf": 2,
              "term_freq": 1
            },
            "hello": {
              "doc_freq": 3,
              "ttf": 3,
              "term_freq": 1
            }
          }
        }
      }
    }
  ]
}

在这里,我们可以看到hello拥有doc_count 3和ttf 3.我怎样才能只考虑具有给定ID的文档。

我想的一种方法是为不同的用户创建不同的索引。但我不确定这种方法是否正确。通过这种方法,指数将随着用户而增加。或者可以有另一种解决方案吗?

1 个答案:

答案 0 :(得分:1)

要获取文档子集的术语doc计数,您可以尝试使用简单聚合。

您必须在字段映射中启用fielddata(尽管内存可能会变得很难,但请查看documentation page about fielddata以获取更多详细信息):

PUT /twitter
{ 
  "mappings": {
    "tweets": {
      "properties": {
        "name": {
          "type": "text",
          "analyzer":"english",
          "fielddata": true,
          "term_vector": "yes"
        }
      }
    }
  }
}

然后使用terms聚合:

POST /twitter/tweets/_search
{
  "size": 0,
  "query": {
    "terms": {
      "_id": [
        "1",
        "2"
      ]
    }
  },
  "aggs": {
    "my_term_doc_count": {
      "terms": {
        "field": "name"
      }
    }
  }
}

回复将是:

{
  "hits": ...,
  "aggregations": {
    "my_term_doc_count": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "hello",
          "doc_count": 2
        },
        {
          "key": "bar",
          "doc_count": 1
        },
        {
          "key": "foo",
          "doc_count": 1
        }
      ]
    }
  }
}

我无法找到计算文档子集total_term_frequency的方法,但我担心无法完成。

我建议使用_analyze API离线计算术语向量,并将它们显式存储在单独的索引中。通过这种方式,您将能够使用简单聚合来计算总术语频率。这里我展示了_analyze API的示例用法。

POST twitter/_analyze
{
  "text": "Hello foo bar"
}

{
  "tokens": [
    {
      "token": "hello",
      "start_offset": 0,
      "end_offset": 5,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "foo",
      "start_offset": 6,
      "end_offset": 9,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "bar",
      "start_offset": 10,
      "end_offset": 13,
      "type": "<ALPHANUM>",
      "position": 2
    }
  ]
}

希望有所帮助!