首页 文章

聚合中的弹性同义词用法

提问于
浏览
0

Situation

使用的弹性版本:2.3.1

我有一个像这样配置的弹性索引

PUT /my_index
{
  "settings": {
    "analysis": {
      "filter": {
        "my_synonym_filter": {
          "type": "synonym", 
          "synonyms": [ 
            "british,english",
            "queen,monarch"
          ]
        }
      },
      "analyzer": {
        "my_synonyms": {
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "my_synonym_filter" 
          ]
        }
      }
    }
  }
}

这很好,当我查询文档并使用查询术语“english " or " queen”时,我得到所有与英国和君主相匹配的文档 . 当我在过滤器聚合中使用同义词时,它不起作用 . 例如

在我的索引中,我有5个文件,其中3个有君主,其中2个有女王

POST /my_index/_search
{
  "size": 0,
  "query" : {
      "match" : {
         "status.synonym":{
            "query": "queen",
            "operator": "and"
         }
      }
   },
     "aggs" : {
        "status_terms" : {
            "terms" : { "field" : "status.synonym" }
        },
        "monarch_filter" : {
            "filter" : { "term": { "status.synonym": "monarch" } }
        }
    },
   "explain" : 0
}

结果产生:

总点击次数:

  • 5 doc doc(正如所料,太棒了!)

  • 状态条款:女王5名医生(正如所料,太棒了!)

  • Monarch过滤器:0个doc count

我尝试了不同的同义词过滤器配置:

  • 女王,君主

  • 女王,君主=>女王

  • 女王,君主=>女王,君主

但是上面没有过滤器,因此我认为我的同义词过滤器配置是错误的 . 可以找到更广泛的同义词过滤器示例here .

QUESTION

如何在过滤器聚合中使用/配置同义词?

Example to replicate the case above :1 . 创建并配置索引:

PUT /my_index
{
  "settings": {
    "analysis": {
      "filter": {
        "my_synonym_filter": {
          "type": "synonym",
          "synonyms": [
            "wlh,wellhead=>wellwell"
          ]
        }
      },
      "analyzer": {
        "my_synonyms": {
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "my_synonym_filter"
          ]
        }
      }
    }
  }
}

PUT my_index/_mapping/job
{
  "properties": {
    "title":{
      "type": "string",
      "analyzer": "my_synonyms"
    }
  }
}

2.输入两份文件:

PUT my_index/job/1
{
    "title":"wellhead smth else"
}

PUT my_index/job/2
{
    "title":"wlh other stuff"
}

3.在wlh上执行搜索,该搜索应返回2个文档;有一个术语聚合,应该有2个井井文件和一个不应该有0个计数的过滤器:

POST my_index/_search
{
  "size": 0,
  "query" : {
      "match" : {
         "title":{
            "query": "wlh",
            "operator": "and"
         }
      }
   },
     "aggs" : {
        "wlhAggs" : {
            "terms" : { "field" : "title" }
        },
        "wlhFilter" : {
            "filter" : { "term": { "title": "wlh"     } }
        }
    },
   "explain" : 0
}

此查询的结果是:

{
   "took": 8,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 2,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "wlhAggs": {
         "doc_count_error_upper_bound": 0,
         "sum_other_doc_count": 0,
         "buckets": [
            {
               "key": "wellwell",
               "doc_count": 2
            },
            {
               "key": "else",
               "doc_count": 1
            },
            {
               "key": "other",
               "doc_count": 1
            },
            {
               "key": "smth",
               "doc_count": 1
            },
            {
               "key": "stuff",
               "doc_count": 1
            }
         ]
      },
      "wlhFilter": {
         "doc_count": 0
      }
   }
}

这就是我的问题,wlhFilter应该至少有1个doc count .

2 回答

  • 1

    我的时间很短,所以如果需要,我可以在今天/明天稍后再详细说明一下 . 但以下应该有效:

    DELETE /my_index
    PUT /my_index
    {
      "settings": {
        "analysis": {
          "filter": {
            "my_synonym_filter": {
              "type": "synonym", 
              "synonyms": [ 
                "british,english",
                "queen,monarch"
              ]
            }
          },
          "analyzer": {
            "my_synonyms": {
              "tokenizer": "standard",
              "filter": [
                "lowercase",
                "my_synonym_filter" 
              ]
            }
          }
        }
      },
      "mappings": {
        "test": {
          "properties": {
            "title": {
              "type": "text",
              "analyzer": "my_synonyms",
              "fielddata": true
            }
          }
        }
      }
    }
    POST my_index/test/1
    {
      "title" : "the british monarch"
    }
    
    GET my_index/_search
    {
      "query": {
        "match": {
          "title": "queen"
        }
      }
    }
    
    GET my_index/_search
    {
      "query": {
        "match": {
          "title": "queen"
        }
      }, 
      "aggs": {
        "queen_filter": {
          "filter": {
            "term": {
              "title": "queen"
            }
          }
        },
        "monarch_filter": {
          "filter": {
            "term": {
              "title": "monarch"
            }
          }
        }
      }
    }
    

    你能分享你为 status.synonym 字段定义的映射吗?

    EDIT: V2

    过滤器输出为0的原因是因为Elasticsearch中的过滤器永远不会经历分析阶段 . 它适用于完全匹配 .

    聚合中的标记'wlh'将不会转换为'wellwell',这意味着它不会出现在倒排索引中 . 这是因为,在索引时,你的'wlh'被翻译成'wellwell' . 为了达到您想要的效果,您必须将数据索引到单独的字段中并相应地调整过滤器 .

    你可以尝试类似的东西:

    DELETE my_index
    PUT /my_index
    {
      "settings": {
        "number_of_shards": 1, 
        "number_of_replicas": 0, 
        "analysis": {
          "filter": {
            "my_synonym_filter": {
              "type": "synonym",
              "synonyms": [
                "wlh,wellhead=>wellwell"
              ]
            }
          },
          "analyzer": {
            "my_synonyms": {
              "tokenizer": "standard",
              "filter": [
                "lowercase",
                "my_synonym_filter"
              ]
            }
          }
        }
      },
      "mappings": {
        "job": {
          "properties": {
            "title": {
              "type": "string",
              "fields": {
                "synonym": {
                  "type": "string",
                  "analyzer": "my_synonyms"
                }
              }
            }
          }
        }
      }
    }
    
    PUT my_index/job/1
    {
        "title":"wellhead smth else"
    }
    
    PUT my_index/job/2
    {
        "title":"wlh other stuff"
    }
    
    POST my_index/_search
    {
      "size": 0,
      "query": {
        "match": {
          "title.synonym": {
            "query": "wlh",
            "operator": "and"
          }
        }
      },
      "aggs": {
        "wlhAggs": {
          "terms": {
            "field": "title.synonym"
          }
        },
        "wlhFilter": {
          "filter": {
            "term": {
              "title": "wlh"
            }
          }
        }
      }
    }
    

    输出:

    {
      "aggregations": {
        "wlhAggs": {
          "doc_count_error_upper_bound": 0,
          "sum_other_doc_count": 0,
          "buckets": [
            {
              "key": "wellwell",
              "doc_count": 2
            },
            {
              "key": "else",
              "doc_count": 1
            },
            {
              "key": "other",
              "doc_count": 1
            },
            {
              "key": "smth",
              "doc_count": 1
            },
            {
              "key": "stuff",
              "doc_count": 1
            }
          ]
        },
        "wlhFilter": {
          "doc_count": 1
        }
      }
    }
    

    希望这可以帮助!!

  • 1

    所以在@Byron Voorbach的帮助下,他的评论是我的解决方案:

    • 我创建了一个单独的字段,我使用同义词分析器,而不是具有属性字段(mainfield.property) .

    • 最重要的是问题是我的同义词已签约!我有,例如,英国,英语=>英国 . 将其更改为英语,英语,英语解决了我的问题,过滤器聚合正在返回正确数量的文档 .

    希望这有助于某人,或者至少指向正确的方向 .

    编辑:哦,主赞美文件!我用Filters(S!)聚合(链接here)完全解决了我的问题 . 在过滤器配置中,我指定了匹配类型的查询,它工作正常!结束了这样的事情:

    "aggs" : {
        "messages" : {
          "filters" : {
            "filters" : {
              "status" :   { "match" : { "cats.saurus" : "monarch"   }},
              "country" : { "match" : { "cats.saurus" : "british" }}
            }
          }
        }
      }
    

相关问题