ElasticSearch 在具有相同名称的列表字段上搜索相同的值
ElasticSearch Searching for same value on list fields with same name
在具有相同名称的字段上搜索相同的值。只有当所有值都是字段 "list.perInd" 是 'IXSO' 时,我才希望在文档下方 return .....
原始文档看起来像这样
{
"pkClmn": 676101388023,
"dutyCde": "RICE",
"list": [
{
"pkClmn": 67610138804,
"perInd": "IXSO",
},
{
"pkClmn": 67610138803,
"perInd": "IXSO",
},
{
"pkClmn": 67610138802,
"perInd": "IASI",
},
{
"pkClmn": 67610138801,
"perInd": "IASI",
}
]
}
return doc only if list.perInd has all 4 IXSO ...
当前的解决方案可能存在一些性能问题,但它有效,您应该对其进行测试
POST stack/type1/1
{
"pkClmn": 676101388023,
"dutyCde": "RICE",
"list": [
{
"pkClmn": 67610138804,
"perInd": "IXSO"
},
{
"pkClmn": 67610138803,
"perInd": "IXSO"
},
{
"pkClmn": 67610138802,
"perInd": "IASI"
},
{
"pkClmn": 67610138801,
"perInd": "IASI"
}
]
}
POST stack/type1/2
{
"pkClmn": 676101388023,
"dutyCde": "RICE",
"list": [
{
"pkClmn": 67610138804,
"perInd": "IXSO"
},
{
"pkClmn": 67610138803,
"perInd": "IXSO"
},
{
"pkClmn": 67610138802,
"perInd": "IXSO"
},
{
"pkClmn": 67610138801,
"perInd": "IXSO"
}
]
}
POST stack/type1/_search
{
"query": {
"filtered": {
"query": {
"term": {
"list.perInd": {
"value": "ixso"
}
}
},
"filter": {
"script": {
"script": "doc['list.perInd'].value == value",
"params": {
value: "ixso"
}
}
}
}
}
}
让我稍微解释一下它的工作原理。 Elasticsearch 使用倒排索引来存储数据。
所以当你索引文档文本被标记化时(再次有很多标记化器可以是单词,可以是几个单词。阅读关于 Elasticsearch 标记器),在标准标记中是一个单词。所以在倒排索引中有术语和对我们示例中文档的引用,它需要 ixso 和 iasi 并将它们写在倒排索引中。因此,如果您有两个术语,那么 doc[fieldname].values 将具有这两个术语的数组,在我的情况下,我正在检查 .value 属性 因为它将被转换为字符串,如果有两个标记,字符串将与参数不同。
还有analyzed and not_analyzed映射。在我的示例中,我使用 analyzed 进行展示,它仅适用于一个术语 perInd。例如,如果您要索引 "test word",我的解决方案将不起作用,因为 doc['list.perInd'].values 将 return ["ixso"、"test"]。如果您使用多个单词,则必须使用 not_analyzed
如您所见,我还使用字符串参数让 elasticsearch 缓存我的过滤器以提高性能。
您的数据模型中有一些需要注意的地方。
首先你的列表是一个嵌套对象,你需要创建一个这样的映射
curl -XPUT "http://192.168.99.100:9200/testt" -d'
{
"mappings": {
"stack": {
"properties": {
"list": {
"type": "nested"
}
}
}
}
}'
现在让我们插入示例数据
curl -XPOST "http://192.168.99.100:9200/testt/stack" -d'
{
"pkClmn": 676101388023,
"dutyCde": "RICE",
"list": [
{
"pkClmn": 67610138804,
"perInd": "IXSO"
},
{
"pkClmn": 67610138803,
"perInd": "IXSO"
},
{
"pkClmn": 67610138802,
"perInd": "IASI"
},
{
"pkClmn": 67610138801,
"perInd": "IASI"
}
]
}'
现在让我们搜索一下
curl -XPOST "http://192.168.99.100:9200/testt/stack/_search" -d'
{
"query": {
"nested": {
"path": "list",
"query": {
"filtered": {
"filter": {
"term": {
"list.perInd": "ixso"
}
}
}
}
}
}
}'
我们将使用带有术语过滤器的嵌套查询,在您的情况下可以缓存过滤器是最佳选择。
希望对你有帮助,有问题可以问我
在具有相同名称的字段上搜索相同的值。只有当所有值都是字段 "list.perInd" 是 'IXSO' 时,我才希望在文档下方 return ..... 原始文档看起来像这样
{
"pkClmn": 676101388023,
"dutyCde": "RICE",
"list": [
{
"pkClmn": 67610138804,
"perInd": "IXSO",
},
{
"pkClmn": 67610138803,
"perInd": "IXSO",
},
{
"pkClmn": 67610138802,
"perInd": "IASI",
},
{
"pkClmn": 67610138801,
"perInd": "IASI",
}
]
}
return doc only if list.perInd has all 4 IXSO ...
当前的解决方案可能存在一些性能问题,但它有效,您应该对其进行测试
POST stack/type1/1
{
"pkClmn": 676101388023,
"dutyCde": "RICE",
"list": [
{
"pkClmn": 67610138804,
"perInd": "IXSO"
},
{
"pkClmn": 67610138803,
"perInd": "IXSO"
},
{
"pkClmn": 67610138802,
"perInd": "IASI"
},
{
"pkClmn": 67610138801,
"perInd": "IASI"
}
]
}
POST stack/type1/2
{
"pkClmn": 676101388023,
"dutyCde": "RICE",
"list": [
{
"pkClmn": 67610138804,
"perInd": "IXSO"
},
{
"pkClmn": 67610138803,
"perInd": "IXSO"
},
{
"pkClmn": 67610138802,
"perInd": "IXSO"
},
{
"pkClmn": 67610138801,
"perInd": "IXSO"
}
]
}
POST stack/type1/_search
{
"query": {
"filtered": {
"query": {
"term": {
"list.perInd": {
"value": "ixso"
}
}
},
"filter": {
"script": {
"script": "doc['list.perInd'].value == value",
"params": {
value: "ixso"
}
}
}
}
}
}
让我稍微解释一下它的工作原理。 Elasticsearch 使用倒排索引来存储数据。
所以当你索引文档文本被标记化时(再次有很多标记化器可以是单词,可以是几个单词。阅读关于 Elasticsearch 标记器),在标准标记中是一个单词。所以在倒排索引中有术语和对我们示例中文档的引用,它需要 ixso 和 iasi 并将它们写在倒排索引中。因此,如果您有两个术语,那么 doc[fieldname].values 将具有这两个术语的数组,在我的情况下,我正在检查 .value 属性 因为它将被转换为字符串,如果有两个标记,字符串将与参数不同。
还有analyzed and not_analyzed映射。在我的示例中,我使用 analyzed 进行展示,它仅适用于一个术语 perInd。例如,如果您要索引 "test word",我的解决方案将不起作用,因为 doc['list.perInd'].values 将 return ["ixso"、"test"]。如果您使用多个单词,则必须使用 not_analyzed
如您所见,我还使用字符串参数让 elasticsearch 缓存我的过滤器以提高性能。
您的数据模型中有一些需要注意的地方。 首先你的列表是一个嵌套对象,你需要创建一个这样的映射
curl -XPUT "http://192.168.99.100:9200/testt" -d'
{
"mappings": {
"stack": {
"properties": {
"list": {
"type": "nested"
}
}
}
}
}'
现在让我们插入示例数据
curl -XPOST "http://192.168.99.100:9200/testt/stack" -d'
{
"pkClmn": 676101388023,
"dutyCde": "RICE",
"list": [
{
"pkClmn": 67610138804,
"perInd": "IXSO"
},
{
"pkClmn": 67610138803,
"perInd": "IXSO"
},
{
"pkClmn": 67610138802,
"perInd": "IASI"
},
{
"pkClmn": 67610138801,
"perInd": "IASI"
}
]
}'
现在让我们搜索一下
curl -XPOST "http://192.168.99.100:9200/testt/stack/_search" -d'
{
"query": {
"nested": {
"path": "list",
"query": {
"filtered": {
"filter": {
"term": {
"list.perInd": "ixso"
}
}
}
}
}
}
}'
我们将使用带有术语过滤器的嵌套查询,在您的情况下可以缓存过滤器是最佳选择。 希望对你有帮助,有问题可以问我