简体   繁体   English

Elasticsearch 排除包含特定术语的文档

[英]Elasticsearch exclude documents containing specific terms

I've indexed documents like bellow in elasticsearch .我已经在elasticsearch索引了像波纹管这样的文档。

{    
    "category": "clothing (f)",
    "description": "Women's Unstoppable Graphic T-Shirt - Women’s Short Sleeve Shirt",
    "name": "Women's Unstoppable Graphic T-Shirt",
    "price": "$34.99"
}

There are categories like clothing (m) , clothing (f) etc. I am trying to exclude the cloting (m) category items if the search is for female items.clothing (m)clothing (f)等类别。如果搜索的是女性物品,我试图排除cloting (m)类别物品。 The query I am trying is:我正在尝试的查询是:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "description": "women's black shirt"
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "category": "clothing (m)"
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 50
}

But this is not working as expected.但这并没有按预期工作。 There are always few results with clothing (m) document with other documents. clothing (m)文件与其他文件的结果总是很少。 How can I exclude documents which have a particular category?如何排除具有特定类别的文档?

In order to exclude a specific term (exact match) you will have to use keyword datatype.为了排除特定term (完全匹配),您必须使用keyword数据类型。

Keyword datatypes are typically used for filtering (Find me all blog posts where status is published), for sorting, and for aggregations.关键字数据类型通常用于过滤(查找已发布状态的所有博客文章)、排序和聚合。 Keyword fields are only searchable by their exact value .关键字字段只能按其确切值进行搜索。

Keyword Datatype 关键字数据类型

Your current query catches clothing (m) in the results because when you indexed your documents they were analyzed with elasticsearch standard analyzer which analyzes clothing (m) as clothing and (m) .您当前的查询在结果中捕获了服装 (m) ,因为当您为文档编制索引时,它们会使用 elasticsearch standard分析器进行分析,该分析器将服装 (m)分析为服装(m)

In your query you searched for category as text datatype.在您的查询中,您将category搜索为text数据类型。

Text datatype fields are analyzed, that is they are passed through an analyzer to convert the string into a list of individual terms before being indexed.文本数据类型字段被分析,也就是说,它们在被索引之前通过分析器将字符串转换为单个术语的列表。

Run this command:运行此命令:

POST my_index/_analyze
{
  "text": ["clothing (m)"]
}

Results:结果:

{
  "tokens" : [
    {
      "token" : "clothing",
      "start_offset" : 0,
      "end_offset" : 8,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "m",
      "start_offset" : 10,
      "end_offset" : 11,
      "type" : "<ALPHANUM>",
      "position" : 1
    }
  ]
}

A working example:一个工作示例:

Assuming you mappings look like that:假设您的映射如下所示:

{
 "my_index" : {
    "mappings" : {
      "properties" : {
        "category" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "description" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "price" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

Let's post a few documents:让我们发布一些文件:

POST my_index/_doc/1
{    
    "category": "clothing (m)",
    "description": "Women's Unstoppable Graphic T-Shirt - Women’s Short Sleeve Shirt",
    "name": "Women's Unstoppable Graphic T-Shirt",
    "price": "$34.99"
}


POST my_index/_doc/2
{    
    "category": "clothing (f)",
    "description": "Women's Unstoppable Graphic T-Shirt - Women’s Short Sleeve Shirt",
    "name": "Women's Unstoppable Graphic T-Shirt",
    "price": "$34.99"
}

Now our query should look like this:现在我们的查询应该是这样的:

GET my_index/_search
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "description": "women's black shirt"
        }
      },
      "filter": {
        "bool": {
          "must_not": {
            "term": {
              "category.keyword": "clothing (m)"
            }
          }
        }
      }
    }
  },
  "from": 0,
  "size": 50
}

The results:结果:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.43301374,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.43301374,
        "_source" : {
          "category" : "clothing (f)",
          "description" : "Women's Unstoppable Graphic T-Shirt - Women’s Short Sleeve Shirt",
          "name" : "Women's Unstoppable Graphic T-Shirt",
          "price" : "$34.99"
        }
      }
    ]
  }
}

Results without using keyword不使用keyword结果

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.43301374,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.43301374,
        "_source" : {
          "category" : "clothing (f)",
          "description" : "Women's Unstoppable Graphic T-Shirt - Women’s Short Sleeve Shirt",
          "name" : "Women's Unstoppable Graphic T-Shirt",
          "price" : "$34.99"
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.43301374,
        "_source" : {
          "category" : "clothing (m)",
          "description" : "Women's Unstoppable Graphic T-Shirt - Women’s Short Sleeve Shirt",
          "name" : "Women's Unstoppable Graphic T-Shirt",
          "price" : "$34.99"
        }
      }
    ]
  }
}

As you can see from the last results we got also clothing (m) .正如您从上次结果中看到的,我们还得到了服装 (m) BTW don't use term for text datatype.顺便说一句,不要对text数据类型使用term use match .使用match

Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM