Elasticsearch 仅匹配且准确地匹配标签数组中的给定标签

如何解决Elasticsearch 仅匹配且准确地匹配标签数组中的给定标签

举个例子,有四个文档

{id: 1,tags :["cat","dog","horse"]}
{id: 2,tags :["dog","cat"]}
{id: 3,tags :["cat"]}
{id: 4,tags :["dog"]}
  1. 如果我用 ["cat"] 查询标签,我应该只会得到 {id: 3,tags :["cat"]}

  2. 如果我用 ["dog"] 查询标签,我应该只会得到 {id: 4,tags :["dog"]}

如何构造这样的查询

解决方法

[更新]:更新的答案适用于 5.x 和 7.x。


您可以为 tagsterm 查询添加长度过滤器。请参阅下面的示例,使用所提供的数据。

对于高于 5.x 的版本(在 7.x 上测试),这需要以特定方式为索引创建映射(如下所述)。

  1. typetags 设置为 keyword

     PUT /my-index/_mapping
     {"properties":{"id":{"type":"integer"},"tags":{"type":"keyword"}}}
    
  2. ORtypetags 设置为 text,并为 fieldata 启用 tags

     PUT /my-index/_mapping
     {"properties":{"id":{"type":"integer"},"tags":{"type":"text","fielddata":true}}}
    

5.x 不需要这种严格的映射。

映射后,索引文档:

PUT /_bulk
{"create": {"_index": "my-index","_id": 1}}
{"id": 1,"tags" :["cat","dog","horse"]}
{"create": {"_index": "my-index","_id": 2}}
{"id": 2,"dog"]}
{"create": {"_index": "my-index","_id": 3}}
{"id": 3,"tags" :["cat"]}
{"create": {"_index": "my-index","_id": 4}}
{"id": 4,"tags" :["dog"]}

现在搜索索引文档:

GET my-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "tags": {
              "value": "cat"
            }
          }
        },{
          "script": {
            "script": "doc['tags'].length == 1"
          }
        }
      ]
    }
  }
}

结果应该返回预期的文档。

重要说明:以上步骤适用于 5.x,但有一处更改:您需要在操作 because you can have more than one document types (and mappings) in one index in ES 5.x 中提供文档类型 (_type)。

,

Elasticsearch 评分算法为具有确切搜索词的文档提供最高分,即在您的情况下为 cat,并且由于您只需要包含完全 cat 的文档,您可以使用 {{1} } param 为 1 值,这样您的结果会更快,因为脚本在搜索期间遍历每个文档时速度很慢。

添加工作示例。

索引示例文档

POST /index/_doc/1

size

文档 2

{
    "id": 1,"tags": [
        "cat","horse"
    ]
}

文档 3

{
    "id": 2,"tags": [
        "dog","cat"
    ]
}

文档 4

{
    "id": 3,"tags": [
        "cat"
    ]
}

和搜索查询

{
    "id": 4,"tags": [
        "dog"
    ]
}

返回搜索结果

{
    "size": 1,// Note
    "query": {
        "bool": {
            "must": [
                {
                    "term": {
                        "tags": {
                            "value": "cat"
                        }
                    }
                }
            ]
        }
    }    
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?