我正在尝试创建一个 Elasticsearch 查询,该查询将对两个字段name和type我的索引执行部分和全文匹配,并返回包含特定uid字段值的所有匹配项。例如,我有以下记录:
{ name: "Doug", "type": "Large"} { name: "Doug Small", "type":"Large"} { name: "Smal", "type": "Medium"} { name: "Peter", "type": "Small"}我希望我的查询能够匹配并返回所有这些记录。这是我到目前为止的查询:
{
"query": {
"bool": {
"must": [
{
"query_string": {
"fields": [
"name",
"type"
],
"query": "*Doug Small*~",
"default_operator": "AND"
}
}
],
"filter": [
{
"match": {
"uid": "123"
}
}
]
}
}
}Run Code Online (Sandbox Code Playgroud)
为了返回任何结果,我必须将查询包装起来,并在末尾*添加模糊。~对于该用例来说,这是正确的查询类型吗?
这是我的映射:
{
"test": {
"mappings": {
"data": {
"properties": {
"uid": {
"type": "keyword"
},
"name": {
"type": "keyword"
},
"type": {
"type": "keyword"
}
}
}
}
}
}Run Code Online (Sandbox Code Playgroud)
这里有多个问题需要考虑。
keyword。这种类型意味着不会分析该字符串(小写、标记化等)。因此,如果您使用完全相同的输入以外的内容进行搜索,那么它将不匹配。例如Doug Small。您可能会认为,既然您使用完全相同的输入进行搜索,至少会返回此文档,但事实并非如此。原因是query_stringorsimple_query_string输入被解析(并因此被标记化)。如果您不将输入指定为一项,那么它将不匹配。为此,您需要用双引号 (" \"Doug Small\" ") 将术语括起来。但如果你这样做,你就会输掉所有其他比赛。text。这意味着将分析保存的字符串(标记化、小写等,请检查简单分析器(如果您不指定其他分析器,则这是默认值)。ANDfor query_string。这意味着所有查询词必须在名称或类型上匹配。但您声明您需要随查询返回所有文档。只有一份文档同时具有Doug和Small。如果您需要这个,那么该运算符必须更改为OR(这是默认值)。一个完整的例子
PUT test
{
"mappings": {
"properties": {
"uid": {
"type": "keyword"
},
"name": {
"type": "text"
},
"type": {
"type": "text"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
POST test/_bulk
{ "index" : { "_id" : "1" } }
{ "name": "Doug", "type": "Large"}
{ "index" : { "_id" : "2" } }
{ "name": "Doug Small", "type":"Large"}
{ "index" : { "_id" : "3" } }
{ "name": "Smal", "type": "Medium"}
{ "index" : { "_id" : "4" } }
{ "name": "Peter", "type": "Small"}
Run Code Online (Sandbox Code Playgroud)
GET test/_search
{
"query": {
"bool": {
"must": [
{
"simple_query_string": {
"fields": [
"name",
"type"
],
"query": "*Doug Small*",
"default_operator": "OR"
}
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的查询现在返回具有Doug或Small/或两者的所有三个文档。此外,不区分大小写(因为现在已经对其进行了分析),因此这*doug small*将产生相同的 3 个结果。
由于现在对字段进行了分析,因此您不需要使用通配符,因为它现在用于第一个标记和最后一个标记。意义
*Doug Small*: 匹配任何有<ANYTHING>DogOR 的东西Small<Anything>*Doug Smith Small*:匹配任何具有<ANYTHING>DogOR SmithOR 的Small<Anything>内容(OR -> 默认运算符,如果保留 AND,则它会相应更改)所以我们也删除通配符
GET test/_search
{
"query": {
"bool": {
"must": [
{
"simple_query_string": {
"fields": [
"name",
"type"
],
"query": "Doug Small",
"default_operator": "OR"
}
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
这会产生完全相同的 3 个结果。你还是失踪了Smal。现在您需要添加模糊匹配才能将其包含在内。
GET test/_search
{
"query": {
"bool": {
"must": [
{
"simple_query_string": {
"fields": [
"name",
"type"
],
"query": "Doug Small~",
"default_operator": "OR"
}
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
这Doug Small~意味着将具有DougOR 的所有内容带到Small其中Small可能不完全匹配的内容。
您可以对所有术语进行模糊匹配
GET test/_search
{
"query": {
"bool": {
"must": [
{
"simple_query_string": {
"fields": [
"name",
"type"
],
"query": "Dg~ Small~",
"default_operator": "OR"
}
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
之所以Dg匹配Doug是因为模糊程度https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#fuzziness
允许的最大编辑编辑距离(或编辑次数)
| 归档时间: |
|
| 查看次数: |
3817 次 |
| 最近记录: |