Elasticsearch查询多个术语

时间:2019-12-24 11:49:30

标签: elasticsearch elasticsearch-query

我正在尝试创建一个搜索查询,该查询允许按名称和类型进行搜索。 我已经索引了这些值,并且我在Elasticsearch中的记录看起来像这样:

{
  _index: "assets",
  _type: "asset",
  _id: "eAOEN28BcFmQazI-nngR",
  _score: 1,
  _source: {
    name: "test.png",
    mediaType: "IMAGE",
    meta: {
      content-type: "image/png",
      width: 3348,
      height: 1890,
    },
    createdAt: "2019-12-24T10:47:15.727Z",
    updatedAt: "2019-12-24T10:47:15.727Z",
  }
}

那么我将如何创建一个查询,查找所有名称为“ test”且为图像的资产?

我尝试了multi_mach查询,但是没有返回正确的结果:

{
  "query": {
    "multi_match" : {
      "query":      "*test* IMAGE",
      "type":       "cross_fields",
      "fields":     [ "name", "mediaType" ],
      "operator":   "and" 
    }
  }
}

上面的查询返回0个结果,如果我将运算符更改为“或”,它将返回IMAGE类型的所有资产。

任何建议将不胜感激。 TIA!

编辑:添加了映射 下面是映射:

{
    "assets": {
        "aliases": {},
        "mappings": {
            "properties": {
                "__v": {
                    "type": "long"
                },
                "createdAt": {
                    "type": "date"
                },
                "deleted": {
                    "type": "date"
                },
                "mediaType": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "meta": {
                    "properties": {
                        "content-type": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "width": {
                            "type": "long"
                        },
                        "height": {
                          "type": "long"
                      }
                    }
                },
                "name": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "originalName": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "updatedAt": {
                    "type": "date"
                }
            }
        },
        "settings": {
            "index": {
                "creation_date": "1575884312237",
                "number_of_shards": "1",
                "number_of_replicas": "1",
                "uuid": "nSiAoIIwQJqXQRTyqw9CSA",
                "version": {
                    "created": "7030099"
                },
                "provided_name": "assets"
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

对于此简单查询,您无需使用通配符表达式。

首先,在name字段中更改您的分析仪。

您需要创建一个自定义分析器,将.替换为space,因为默认的标准分析器不会这样做,以便您在搜索test时得到{{1} },因为倒排索引中将同时包含test.pngtest这样做的主要好处是避免了非常昂贵的正则表达式查询

使用自定义分析器更新了映射,它将为您完成工作。只需更新您的映射并重新为所有文档重新编制索引即可。

png

第二,您应该将查询更改为布尔查询,如下所示:

{
    "aliases": {},
    "mappings": {
        "properties": {
            "__v": {
                "type": "long"
            },
            "createdAt": {
                "type": "date"
            },
            "deleted": {
                "type": "date"
            },
            "mediaType": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            },
            "meta": {
                "properties": {
                    "content-type": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "width": {
                        "type": "long"
                    },
                    "height": {
                        "type": "long"
                    }
                }
            },
            "name": {
                "type": "text",
                "analyzer" : "my_analyzer"
            },
            "originalName": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            },
            "updatedAt": {
                "type": "date"
            }
        }
    },
    "settings": {
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "tokenizer": "standard",
                    "char_filter": [
                        "replace_dots"
                    ]
                }
            },
            "char_filter": {
                "replace_dots": {
                    "type": "mapping",
                    "mappings": [
                        ". => \\u0020"
                    ]
                }
            }
        },
        "index": {
            "number_of_shards": "1",
            "number_of_replicas": "1"
        }
    }
}

将must与2个match查询一起使用意味着,仅当must查询的所有子句都匹配时,它才会返回docs。

我已经通过创建索引,插入一些示例文档并进行查询来测试我的解决方案,让我知道您是否需要任何帮助。

答案 1 :(得分:0)

您尝试过使用 best_fields 吗?

{
  "query": {
    "multi_match" : {
      "query":      "Will Smith",
      "type":       "best_fields",
      "fields":     [ "name", "mediaType" ],
      "operator":   "and" 
    }
  }
}