Elasticsearch更像是这个查询

时间:2015-02-03 20:32:02

标签: elasticsearch morelikethis

我正在尝试围绕more like this查询的工作方式,我似乎错过了一些东西。我阅读了文档,但ES文档通常有点......缺乏。

目标是能够按照here尝试的术语频率限制结果。

所以我设置了一个简单的索引,包括用于调试的术语向量,然后添加了两个简单的文档。

DELETE /test_index

PUT /test_index
{
   "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 0
   },
   "mappings": {
      "doc": {
         "properties": {
            "text": {
               "type": "string",
               "term_vector": "yes"
            }
         }
      }
   }
}

PUT /test_index/doc/1
{
    "text": "apple, apple, apple, apple, apple"
}

PUT /test_index/doc/2
{
    "text": "apple, apple"
}

当我看到termvectors时,我看到了我的期望:

GET /test_index/doc/1/_termvector
...
{
   "_index": "test_index",
   "_type": "doc",
   "_id": "1",
   "_version": 1,
   "found": true,
   "term_vectors": {
      "text": {
         "field_statistics": {
            "sum_doc_freq": 2,
            "doc_count": 2,
            "sum_ttf": 7
         },
         "terms": {
            "apple": {
               "term_freq": 5
            }
         }
      }
   }
}

GET /test_index/doc/2/_termvector
{
   "_index": "test_index",
   "_type": "doc",
   "_id": "2",
   "_version": 1,
   "found": true,
   "term_vectors": {
      "text": {
         "field_statistics": {
            "sum_doc_freq": 2,
            "doc_count": 2,
            "sum_ttf": 7
         },
         "terms": {
            "apple": {
               "term_freq": 2
            }
         }
      }
   }
}

当我使用"min_term_freq": 1运行以下查询时,我会找回两个文档:

POST /test_index/_search
{
   "query": {
      "more_like_this": {
         "fields": [
            "text"
         ],
         "like_text": "apple",
         "min_term_freq": 1,
         "percent_terms_to_match": 1,
         "min_doc_freq": 1
      }
   }
}
...
{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 2,
      "max_score": 0.5816214,
      "hits": [
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "1",
            "_score": 0.5816214,
            "_source": {
               "text": "apple, apple, apple, apple, apple"
            }
         },
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "2",
            "_score": 0.5254995,
            "_source": {
               "text": "apple, apple"
            }
         }
      ]
   }
}

但是,如果我将"min_term_freq"增加到2(或更多),我什么也得不到,虽然我希望能够返回两个文件:

POST /test_index/_search
{
   "query": {
      "more_like_this": {
         "fields": [
            "text"
         ],
         "like_text": "apple",
         "min_term_freq": 2,
         "percent_terms_to_match": 1,
         "min_doc_freq": 1
      }
   }
}
...
{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 0,
      "max_score": null,
      "hits": []
   }
}

为什么呢?我错过了什么?

如果我想设置一个查询,只返回"apple"出现5次的文档,而不是出现2次的文档,那么还有更好的方法吗?

以下是代码,为方便起见:

http://sense.qbox.io/gist/341f9f77a6bd081debdcaa9e367f5a39be9359cc

2 个答案:

答案 0 :(得分:7)

在进行MLT之前,最小术语频率和最小文档频率实际应用于输入。 这意味着,由于您的输入文本中只有一次出现苹果,因此最小术语频率设置为2时,苹果从未获得MLT资格。 如果您将输入更改为" apple apple"如下所示,事情会奏效 -

POST /test_index/_search
{
   "query": {
      "more_like_this": {
         "fields": [
            "text"
         ],
         "like_text": "apple apple",
         "min_term_freq": 2,
         "percent_terms_to_match": 1,
         "min_doc_freq": 1
      }
   }
}

同样适用于min doc频率。 Apple位于至少2个文档中,因此min_doc_freq最多为2将符合MLT操作的输入文本。

答案 1 :(得分:1)

作为这个问题的发布者,我也试图围绕more_like_this查询...

我在网络上寻找良好的信息资源有些费劲,但是(在大多数情况下)文档似乎最有用,因此,这里是the link to the documentation,还有一些更重要的术语(和/或有点难以理解,所以我加了我的解释):

max_query_terms-将被选择的最大查询词数(来自每个输入文档的 )。增大此值可提高准确性,但会降低查询执行速度。默认值为25。

min_term_freq-最小术语频率,低于该频率的术语将从输入文档中忽略。默认为2。

  

如果该术语在输入文档中出现的次数少于2次(默认值),则会从输入文档中忽略,即不会在其他more_like_this个文档中进行搜索。

min_doc_freq-最小文档频率,低于此频率时,输入文档中的术语将被忽略。默认值为5。

这花了我一秒钟,所以,这是我的解释:

  

输入文档中的一个术语必须出现在多少个文档中才能被选择为查询术语。

在那里,我希望我能救一个人几分钟的生命。 :)

干杯!