首页 > 解决方案 > 查询 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

解决方案


您似乎正在使用 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"
}

让我知道这是否解决了您的问题。


推荐阅读