如何在 elasticsearch 中找到所有在某个字段中包含数字的文档?
How can I find all documents in elasticsearch that contain a number in a certain field?
我有一个 keyword
类型的字段,可以包含数字或字符串。如果该字段不包含任何字母,我想点击该文件。我该怎么做?
我的索引映射如下:
{
"mappings": {
"Entry": {
"properties": {
"testField": {
"type": "keyword"
}
}
}
}
}
我的文档是这样的:
{
"testField":"123abc"
}
或
{
"testField": "456789"
}
我试过查询:
{
"query": {
"range": {
"gte": 0,
"lte": 2000000
}
}
}
但它仍然点击 123abc
。我如何设计它以便我只点击在该特定字段中带有数字的文档?
Afaik,Elasticsearch 对此没有直接的解决方案。
相反,您需要编写 Script Query。以下是您要查找的内容:
POST <your_index_name>/_search
{
"query": {
"bool": {
"must": [
{
"script": {
"script": {
"lang": "painless",
"source": """
try{
String temp = doc['testField'].value;
int a = Integer.parseInt(temp);
if(a instanceof Integer)
return true;
}catch(NumberFormatException e){
return false;
}
"""
}
}
}
]
}
}
}
希望对您有所帮助!
还有另一个更好的选择来实现你想要的。您可以利用 ingest API pipelines and using a script
processor 您可以在索引时创建另一个数字字段,然后您可以在搜索时更有效地使用它。
下面的摄取管道包含一个 script
处理器,它将创建另一个名为 numField
的字段,该字段将仅包含数值。
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"script": {
"source": """
ctx.numField = /\D/.matcher(ctx.testField).replaceAll("");
"""
}
}
]
},
"docs": [
{
"_source": {
"testField": "123"
}
},
{
"_source": {
"testField": "abc123"
}
},
{
"_source": {
"testField": "123abc"
}
},
{
"_source": {
"testField": "abc"
}
}
]
}
用 4 个混合了字母数字内容的不同文档模拟此管道,将产生以下结果:
{
"docs" : [
{
"doc" : {
"_index" : "_index",
"_type" : "_type",
"_id" : "_id",
"_source" : {
"numField" : "123",
"testField" : "123"
},
"_ingest" : {
"timestamp" : "2019-05-09T04:14:51.448Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_type",
"_id" : "_id",
"_source" : {
"numField" : "123",
"testField" : "abc123"
},
"_ingest" : {
"timestamp" : "2019-05-09T04:14:51.448Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_type",
"_id" : "_id",
"_source" : {
"numField" : "123",
"testField" : "123abc"
},
"_ingest" : {
"timestamp" : "2019-05-09T04:14:51.448Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_type",
"_id" : "_id",
"_source" : {
"numField" : "",
"testField" : "abc"
},
"_ingest" : {
"timestamp" : "2019-05-09T04:14:51.448Z"
}
}
}
]
}
索引文档 using this pipeline 后,您可以 运行 在 numField
而不是 testField
上进行范围查询。与其他解决方案(抱歉@Kamal)相比,它会将脚本负担转移到 运行 每个文档在索引时仅一次,而不是每次在搜索时每个文档上。
{
"query": {
"range": {
"numField": {
"gte": 0,
"lte": 2000000
}
}
}
}
我有一个 keyword
类型的字段,可以包含数字或字符串。如果该字段不包含任何字母,我想点击该文件。我该怎么做?
我的索引映射如下:
{
"mappings": {
"Entry": {
"properties": {
"testField": {
"type": "keyword"
}
}
}
}
}
我的文档是这样的:
{
"testField":"123abc"
}
或
{
"testField": "456789"
}
我试过查询:
{
"query": {
"range": {
"gte": 0,
"lte": 2000000
}
}
}
但它仍然点击 123abc
。我如何设计它以便我只点击在该特定字段中带有数字的文档?
Afaik,Elasticsearch 对此没有直接的解决方案。
相反,您需要编写 Script Query。以下是您要查找的内容:
POST <your_index_name>/_search
{
"query": {
"bool": {
"must": [
{
"script": {
"script": {
"lang": "painless",
"source": """
try{
String temp = doc['testField'].value;
int a = Integer.parseInt(temp);
if(a instanceof Integer)
return true;
}catch(NumberFormatException e){
return false;
}
"""
}
}
}
]
}
}
}
希望对您有所帮助!
还有另一个更好的选择来实现你想要的。您可以利用 ingest API pipelines and using a script
processor 您可以在索引时创建另一个数字字段,然后您可以在搜索时更有效地使用它。
下面的摄取管道包含一个 script
处理器,它将创建另一个名为 numField
的字段,该字段将仅包含数值。
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"script": {
"source": """
ctx.numField = /\D/.matcher(ctx.testField).replaceAll("");
"""
}
}
]
},
"docs": [
{
"_source": {
"testField": "123"
}
},
{
"_source": {
"testField": "abc123"
}
},
{
"_source": {
"testField": "123abc"
}
},
{
"_source": {
"testField": "abc"
}
}
]
}
用 4 个混合了字母数字内容的不同文档模拟此管道,将产生以下结果:
{
"docs" : [
{
"doc" : {
"_index" : "_index",
"_type" : "_type",
"_id" : "_id",
"_source" : {
"numField" : "123",
"testField" : "123"
},
"_ingest" : {
"timestamp" : "2019-05-09T04:14:51.448Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_type",
"_id" : "_id",
"_source" : {
"numField" : "123",
"testField" : "abc123"
},
"_ingest" : {
"timestamp" : "2019-05-09T04:14:51.448Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_type",
"_id" : "_id",
"_source" : {
"numField" : "123",
"testField" : "123abc"
},
"_ingest" : {
"timestamp" : "2019-05-09T04:14:51.448Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_type",
"_id" : "_id",
"_source" : {
"numField" : "",
"testField" : "abc"
},
"_ingest" : {
"timestamp" : "2019-05-09T04:14:51.448Z"
}
}
}
]
}
索引文档 using this pipeline 后,您可以 运行 在 numField
而不是 testField
上进行范围查询。与其他解决方案(抱歉@Kamal)相比,它会将脚本负担转移到 运行 每个文档在索引时仅一次,而不是每次在搜索时每个文档上。
{
"query": {
"range": {
"numField": {
"gte": 0,
"lte": 2000000
}
}
}
}