Link Search Menu Expand Document Documentation Menu

词项查询

使用 terms 查询在同一字段中搜索多个词项。例如,以下查询搜索 ID 为 6180961810 的行

GET shakespeare/_search
{
  "query": {
    "terms": {
      "line_id": [
        "61809",
        "61810"
      ]
    }
  }
}

如果文档与数组中的任何词项匹配,则返回该文档。

默认情况下,terms 查询允许的最大词项数为 65,536。要更改最大词项数,请更新 index.max_terms_count 设置。

为了获得更好的查询性能,请以排序顺序(按 UTF-8 字节值升序排列)传递包含词项的长数组。

词项查询的结果高亮显示功能可能无法保证,具体取决于高亮显示器类型和查询中的词项数量。

参数

该查询接受以下参数。所有参数均为可选。

参数 数据类型 描述
<field> 字符串 要搜索的字段。仅当文档的字段值与至少一个词项精确匹配(包括正确的间距和大小写)时,才会在结果中返回该文档。
提升 浮点数 一个浮点值,指定此字段对相关性得分的权重。高于 1.0 的值会增加字段的相关性。介于 0.0 和 1.0 之间的值会降低字段的相关性。默认值为 1.0。
_name 字符串 用于查询标记的查询名称。可选。
value_type 字符串 指定用于过滤的值类型。有效值为 defaultbitmap。如果省略,则默认值为 default

词项查找

词项查找检索单个文档的字段值,并将其用作搜索词项。您可以使用词项查找来搜索大量词项。

要使用词项查找,您必须启用 _source 映射字段,因为词项查找从文档中获取值。_source 字段默认启用。

词项查找尝试从本地数据节点上的分片获取文档字段值。因此,使用具有单个主分片并在所有适用数据节点上具有完整副本的索引可以减少网络流量。

示例

举例来说,创建一个包含学生数据的索引,将 student_id 映射为 keyword

PUT students
{
  "mappings": {
    "properties": {
      "student_id": { "type": "keyword" }
    }
  }
}

接下来,索引三个与学生对应的文档

PUT students/_doc/1
{
  "name": "Jane Doe",
  "student_id" : "111"
}

PUT students/_doc/2
{
  "name": "Mary Major",
  "student_id" : "222"
}

PUT students/_doc/3
{
  "name": "John Doe",
  "student_id" : "333"
}

创建一个单独的索引,其中包含班级信息,包括班级名称和与班级中注册学生对应的学生 ID 数组

PUT classes/_doc/101
{
  "name": "CS101",
  "enrolled" : ["111" , "222"]
}

要搜索注册 CS101 班级的学生,请指定与该班级对应的文档 ID、该文档的索引以及词项所在字段的路径

GET students/_search
{
  "query": {
    "terms": {
      "student_id": {
        "index": "classes",
        "id": "101",
        "path": "enrolled"
      }
    }
  }
}

响应包含 students 索引中所有学生(其 ID 与 enrolled 数组中的某个值匹配)的文档

{
  "took": 13,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "students",
        "_id": "1",
        "_score": 1,
        "_source": {
          "name": "Jane Doe",
          "student_id": "111"
        }
      },
      {
        "_index": "students",
        "_id": "2",
        "_score": 1,
        "_source": {
          "name": "Mary Major",
          "student_id": "222"
        }
      }
    ]
  }
}

示例:嵌套字段

第二个示例演示了查询嵌套字段。考虑一个包含以下文档的索引

PUT classes/_doc/102
{
  "name": "CS102",
  "enrolled_students" : {
    "id_list" : ["111" , "333"]
  }
}

要搜索注册 CS102 的学生,请使用点路径表示法在 path 参数中指定字段的完整路径

GET students/_search
{
  "query": {
    "terms": {
      "student_id": {
        "index": "classes",
        "id": "102",
        "path": "enrolled_students.id_list"
      }
    }
  }
}

响应包含匹配文档:

{
  "took": 18,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "students",
        "_id": "1",
        "_score": 1,
        "_source": {
          "name": "Jane Doe",
          "student_id": "111"
        }
      },
      {
        "_index": "students",
        "_id": "3",
        "_score": 1,
        "_source": {
          "name": "John Doe",
          "student_id": "333"
        }
      }
    ]
  }
}

参数

下表列出了词项查找参数。

参数 数据类型 描述
index 字符串 要从中获取字段值的索引名称。必需。
id 字符串 要从中获取字段值的文档 ID。必需。
路径 字符串 要从中获取字段值的字段名称。使用点路径表示法指定嵌套字段。必需。
路由 字符串 要从中获取字段值的文档的自定义路由值。可选。如果在索引文档时提供了自定义路由值,则为必需。
存储 布尔型 是否对存储字段而不是 _source 执行查找。可选。

位图过滤

2.17 版本引入

terms 查询可以同时过滤多个词项。但是,当输入过滤器中的词项数量增加到很大的值(大约 10,000)时,由此产生的网络和内存开销可能会变得很大,导致查询效率低下。在这种情况下,考虑使用 roaring bitmap 对大型词项过滤器进行编码,以实现更高效的过滤。

以下示例假设您有两个索引:一个 products 索引,其中包含公司销售的所有产品;另一个 customers 索引,其中存储了代表拥有特定产品的客户的过滤器。

首先,创建一个 products 索引并将 product_id 映射为整数

PUT /products
{
  "mappings": {
    "properties": {
      "product_id": { "type": "integer" }
    }
  }
}

接下来,索引三个与产品对应的文档

PUT /products/_doc/1
{
  "name": "Product 1",
  "product_id" : 111
}

PUT /products/_doc/2
{
  "name": "Product 2",
  "product_id" : 222
}

PUT /products/_doc/3
{
  "name": "Product 3",
  "product_id" : 333
}

为了存储客户位图过滤器,您将在 customers 索引中创建一个 customer_filter 二进制字段。将 store 指定为 true 以存储该字段

PUT /customers
{
  "mappings": {
    "properties": {
      "customer_filter": {
        "type": "binary",
        "store": true
      }
    }
  }
}

对于每个客户,您需要生成一个位图,表示客户拥有的产品 ID。此位图有效地编码了该客户的过滤条件。在此示例中,您将为 ID 为 customer123 且拥有产品 111222333 的客户创建一个 terms 过滤器。

要为客户编码 terms 过滤器,首先为该过滤器创建一个 roaring bitmap。此示例使用 [PyRoaringBitMap] 库创建位图,因此首先运行 pip install pyroaring 来安装该库。然后序列化位图并使用 Base64 编码方案对其进行编码

from pyroaring import BitMap
import base64

# Create a bitmap, serialize it into a byte string, and encode into Base64
bm = BitMap([111, 222, 333]) # product ids owned by a customer
encoded = base64.b64encode(BitMap.serialize(bm))

# Convert the Base64-encoded bytes to a string for storage or transmission
encoded_bm_str = encoded.decode('utf-8')

# Print the encoded bitmap
print(f"Encoded Bitmap: {encoded_bm_str}")

接下来,将客户过滤器索引到 customers 索引中。该过滤器的文档 ID 与相应客户的 ID 相同(在此示例中为 customer123)。customer_filter 字段包含您为该客户生成的位图

POST customers/_doc/customer123
{
  "customer_filter": "OjAAAAEAAAAAAAIAEAAAAG8A3gBNAQ==" 
}

现在,您可以在 products 索引上运行 terms 查询,以在 customers 索引中查找特定客户。因为您正在查找存储字段而不是 _source,所以将 store 设置为 true。在 value_type 字段中,将 terms 输入的数据类型指定为 bitmap

POST /products/_search
{
  "query": {
    "terms": {
      "product_id": {
        "index": "customers",
        "id": "customer123",
        "path": "customer_filter",
        "store": true               
      },
      "value_type": "bitmap"      
    }
  }
}

您还可以直接将位图传递给 terms 查询。在此示例中,product_id 字段包含 ID 为 customer123 的客户的客户过滤器位图

POST /products/_search
{
  "query": {
    "terms": {
      "product_id": [
        "OjAAAAEAAAAAAAIAEAAAAG8A3gBNAQ=="
      ],
      "value_type": "bitmap"
    }
  }
}

剩余 350 字符

有问题?

想贡献吗?