跨多个字段的not_analyzed字符串数组的完全匹配

时间:2016-11-15 02:16:30

标签: search elasticsearch match search-engine

这是针对elasticsearch 2.3

让我假装我有一个排序的映射:

索引1:

'title': {'type': 'string'},
'tags': {'type': 'string', 'index': 'not_analyzed'} 

索引2:

'title': {'type': 'string'},
'tags': {'type': 'string', 'index': 'not_analyzed'},
'tag_special': {'type': 'string', 'index': 'not_analyzed'}

注意:当推送到index1和index2时,“tags”是一个字符串数组。在index2中,“tag_special”只是一个字符串

我想要完成的是一个查询,我们在这两个索引中进行查询,首先查找index1中的标记数组中的精确term匹配或index2中tag_special的单个字符串值,以及boost那些匹配到堆顶部。然后,我想采用相同的查询,然后针对两个索引的标题字段运行正常的match查询

示例文档

{
  "_index": "index1",
  "_type": "index1",
  "title": "Test Doc 1",
  "tags": ["tag-1", "tag-2"]
}

{
  "_index": "index1",
  "_type": "index1",
  "title": "Test Doc 2",
  "tags": ["tag-1"]
}

{
  "_index": "index1",
  "_type": "index1",
  "title": "Test Doc 3",
  "tags": ["tag-2", "tag-3"]
}

{
  "_index": "index2",
  "_type": "index2",
  "title": "Test Doc inx2 1",
  "tags": ["tag-1", "tag-2"],
  "tag_special": "tag-1"
}

{
  "_index": "index2",
  "_type": "index2",
  "title": "Test Doc inx2 2",
  "tags": ["tag-2"]
}

{
  "_index": "index2",
  "_type": "index2",
  "title": "Test Doc inx2 3",
  "tags": ["tag-3"],
  "tag_special": "tag-4"
}

绝对没有我正在努力的事情正在努力。

"query": {
    "bool": {
        "should": [
            {"term": {"tags": "tag-2"}},
        ]
    }
}
奇怪的是,

没有回报,但是

"query": {
    "bool": {
        "should": [
            {"match": {"tags": "tag-2"}},
        ]
    }
}

返回太多(如果您使用分析器查找“tag-2”并搜索“tag”以及“2”,它将返回所有帖子)

一旦我可以对一个字符串数组进行术语查询,我需要将完全匹配提升到结果的顶部,然后对标题字段使用标准匹配

没有任何术语查询实际匹配任何内容,它们应该是完全可选的。因此,匹配字词不能充当filtersconstant_score,因为我需要它才能进行正常的标题查询,并按分数值排序结果

到目前为止我所拥有的是

"query": {
            "bool": {
                "should": [
                    {"term": {"tags": "tag-2"}},
                    {"term": {"tag_special": "tag-2"}},
                    {"match": {"title": {"query": "tag-2", "operator": "and"}}}
                ],
            }
        }

但是从右边开始,没有任何东西被归还。使用multi_match似乎也是因为它使用匹配子句

我觉得我想要完成的事情实际上非常简单,比如只有一个的东西,我在这里失踪了,而且我在这里因为经过几个小时的试验和错误后,它已经接近退出时间了,我我希望我明天早上能继续做什么哈哈

谢谢你的时间!

2 个答案:

答案 0 :(得分:0)

我和你一样做了,我得到了你的示例文档的结果。在你发布的查询中有一个小问题,因为在bool查询中有“,”,尽管只有一个应该。所以查询应该是这样的。

"query": {
        "bool": {
            "should": [
                {"term": {"tags": "tag-2"}},
                {"term": {"tag_special": "tag-2"}},
                {"match": {"title": {"query": "tag-2", "operator": "and"}}}
            ]
        }
    }

如果这不起作用,请确保将标记和tag_special字段设置为not_analyzed

GET index1/_mapping应显示此结果

"index1": {
  "mappings": {
     "index1": {
        "properties": {
           "tags": {
              "type": "string",
              "index": "not_analyzed"
           },
           "title": {
              "type": "string"
           }
        }
     }
  }
}

如果标签和tag_special fied是analyzed,则术语查询不会给出任何结果

答案 1 :(得分:0)

弄清楚我的问题。它与任何事情无关,但无论如何我都会回答它。

我实际上有两个问题不会在这里显示,但作为一个警示故事。

  1. 我忘了实际发送映射。因此,每次我重新创造"在索引中,地图只会根据我所加入的文件的假设创建自己的自我。
  2. 一旦我实际发送了映射,它仍然无法正常工作,奇怪的是在发送映射并等待从原始数据库中收集文档后,我无法查看任何映射信息,直到文档上传到ES。我发现我不小心使用array作为映射中我的一个不相关字段的类型,而不是string。而且显然没有告诉我有错误,它只是决定完全使地图无效而且在文件上传之前不会打扰。我在那个领域中将array更改为string的那一刻,一切都像魅力一样。