elasticsearch - 查询 elasticSearch 和嵌套对象的问题
问题描述
我对查询 ElasticSearch 有疑问。我想在嵌套对象中查找关于两个值的文档,我应该得到这个结果:
{
"took": 36,
"timed_out": false,
"_shards": {
"total": 6,
"successful": 6,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 6.3647356,
"hits": [
{
"_index": "product2019",
"_type": "product",
"_id": "2561571",
"_score": 6.3647356,
"_source": {
"attribute": [
{
"value": "api gl2",
"type": "887",
"lang": "fr",
"country": "FR",
"numpro": "887"
}
],
"idProduct": "2561571",
"type": "ARTICLE"
}
},
{
"_index": "product2019",
"_type": "product",
"_id": "2562471",
"_score": 6.3647356,
"_source": {
"attribute": [
{
"value": "api gl2",
"type": "887",
"lang": "fr",
"country": "FR",
"numpro": "887"
}
],
"idProduct": "2562471",
"type": "ARTICLE"
}
}
]
}
}
但是根据我的查询,我没有得到好的结果。这是我的查询:
{
"size": 500,
"query": {
"bool": {
"must": {
"nested": {
"query": {
"bool": {
"must": [
{
"term": {
"attribute.numpro": "887"
}
},
{
"term": {
"attribute.value": "api gl2"
}
}
]
}
},
"path": "attribute"
}
},
"minimum_should_match": "1"
}
}
}
使用此查询,结果 = 0。有人可以向我解释为什么我没有正确的结果?
这是我的映射:
{
"mappings":{
"product":{
"properties":{
"type":{
"index":"not_analyzed",
"type":"string"
},
"idProduct":{
"index":"not_analyzed",
"type":"string"
},
"attribute":{
"type":"nested",
"properties":{
"country":{
"index":"not_analyzed",
"type":"string"
},
"lang":{
"index":"not_analyzed",
"type":"string"
},
"type":{
"index":"not_analyzed",
"type":"string"
},
"value":{
"analyzer":"french",
"type":"string",
"fields":{
"value.lowercase":{
"analyzer":"lowercase",
"type":"string"
},
"value.notanalyzed":{
"index":"not_analyzed",
"type":"string"
},
"value.alphanumlower":{
"analyzer":"alphanumlower",
"type":"string"
}
}
},
"numpro":{
"type":"long"
}
}
}
}
}
}
}
解决方案
您似乎正在使用 Elasticsearch 2.x 语法。
对于多字段,您不必重复字段名称(例如,而"value.lowercase":
不仅仅是使用"lowercase":
)。
通过此修复,您的映射应如下所示:
{
"mappings":{
"product":{
"properties":{
"type":{
"index":"not_analyzed",
"type":"string"
},
"idProduct":{
"index":"not_analyzed",
"type":"string"
},
"attribute":{
"type":"nested",
"properties":{
"country":{
"index":"not_analyzed",
"type":"string"
},
"lang":{
"index":"not_analyzed",
"type":"string"
},
"type":{
"index":"not_analyzed",
"type":"string"
},
"value":{
"analyzer":"french",
"type":"string",
"fields":{
"lowercase":{
"analyzer":"lowercase",
"type":"string"
},
"notanalyzed":{
"index":"not_analyzed",
"type":"string"
},
"alphanumlower":{
"analyzer":"alphanumlower",
"type":"string"
}
}
},
"numpro":{
"type":"long"
}
}
}
}
}
}
}
在您的查询中,您需要查询未分析的多字段版本:
{
"term": {
"attribute.value.notanalyzed": "api gl2"
}
}
请记住,在您的点击中,您仍然会看到匹配文档的所有属性。如果您希望 Elasticsearch 还返回导致匹配的特定属性,则必须将其添加"inner_hits" : {}
到嵌套查询中。
不幸的是,我无法测试代码,因为我手头不再有 Elasticsearch v2.x 或 v5.x。从 Elasticsearch 版本 5 开始,类型string
被替换为类型text
(已分析)和keyword
(未分析)。默认情况下,字符串现在被映射到一个多字段,其中<field-name>
指的是已分析的文本字段,并<field-name>.keyword
指的是未分析的关键字字段。如果您使用的是 Elasticsearch 版本 5,您可能需要考虑使用版本 5 语法,这将使您的映射更容易。
例如,此版本 2 映射:
"lang":{
"index":"not_analyzed",
"type":"string"
}
在版本 5 中看起来像这样:
"lang":{
"type":"keyword"
}
让我知道这是否解决了您的问题。
推荐阅读
- phpunit - 如何在 CakePHP 3 中将控制器动作的单元测试与组件分开
- javascript - 承诺无法读取未定义的属性
- php - 如何在 php 上对 Shift_JIS 进行 urlencode?
- juniper - 如何查找上次使用 JUNOS SRX 防火墙策略的时间
- laravel - laravel 5.7中雄辩的一对多关系
- javascript - 升级 webpack4 webpack-merge 反应问题
- javascript - 用于选择的 JavaScript/Jquery 事件,其中 onchange 在执行操作后将选择恢复为默认值
- c# - 防止创建空 xmlns 属性
- sql - 创建具有条件的表并来自多个来源
- python - 在 windows 中使用 word2vec 进行词嵌入时出错