【问题标题】:Remove stopwords while querying using GET Request in Elasticsearch在 Elasticsearch 中使用 GET 请求进行查询时删除停用词
【发布时间】:2019-09-02 10:15:20
【问题描述】:

我正在尝试在 Elasticsearch 的索引中实现 Stop Token Filter。我遵循了取自 here 的代码。

PUT /test1
{
"settings": {
    "analysis": {
        "filter": {
            "my_stop": {
                "type":       "stop",
                "stopwords":  "_english_"
            }

        }
    }
}
} 

我的数据以JSON 格式存储,并且有一个名为Ingredients 的字段,其中包含停用词。我想在整个索引(包含近 8 万条记录)中搜索 Ingredients 标签中出现次数最多的前 100 个值。我用来检索结果的查询是

GET test1/_search?size=0&pretty
{
"aggs": {
"genres": {
  "terms": {
    "field": "Ingredients",
    "size": 100,
    "exclude": "[0-9].*"
  }
}
}
}

我需要从中排除我使用exclude 的数字。 但是使用Kibana 应用上述查询它不会删除Stop Words 并在查询响应时保持它们显示。 根据文档,它应该删除停止的单词,但它没有这样做。我无法找到原因,因为我是Elasticsearch 的新手。请帮我弄清楚。 我正在使用elasticsearch-7.3.1Kibana-7.3.1。 我正在研究它大约两天,但没有一种方法有效。谢谢!任何帮助将不胜感激。

如果我尝试使用这种方式,它可以工作,但是在按照上面定义的方法发出GET 请求时,它根本不起作用。

POST test1/_analyze
{
 "analyzer": "my_stop",
 "text": "House of Dickson<br> corp"
 }

我的地图

    {
      "recipe_test" : {
"aliases" : { },
"mappings" : {
  "properties" : {
    "Author" : {
      "properties" : {
        "additionalInfo" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "description" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "eval" : {
          "type" : "boolean"
        },
        "url" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "value" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    },
    "Category" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "Channel" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "Cousine" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "Ingredients" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      },
      "fielddata" : true
    },
    "Keywords" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "MakingMethod" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "Publication" : {
      "properties" : {
        "additionalInfo" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "eval" : {
          "type" : "boolean"
        },
        "published" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "url" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "value" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    },
    "Rating" : {
      "properties" : {
        "bestRating" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "ratingCount" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "ratingValue" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "worstRating" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    },
    "Servings" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "Timings" : {
      "properties" : {
        "cookTime" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "prepTime" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "totalTime" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    },
    "Title" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "description" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    },
    "recipe_url" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    }
  }
},
"settings" : {
  "index" : {
    "number_of_shards" : "1",
    "provided_name" : "recipe_test",
    "creation_date" : "1567443878756",
    "analysis" : {
      "filter" : {
        "english_stop" : {
          "type" : "stop",
          "stopwords" : "_english_"
        }
      },
      "analyzer" : {
        "rebuilt_stop" : {
          "filter" : [
            "asciifolding",
            "lowercase",
            "english_stop"
          ],
          "tokenizer" : "standard"
        }
      }
    },
    "number_of_replicas" : "1",
    "uuid" : "K-FrOyc6QlWokGQoN6HxCg",
    "version" : {
      "created" : "7030199"
    }
  }
}

} }

我的示例数据

{
"recipe_url": "http1742637/bean-and-pesto-mash",
"Channel": "waqas",
 "recipe_id":"31",
"Title": "Bean & pesto mash",
"Rating": {
    "ratingValue": "4.625",
    "bestRating": "5",
    "worstRating": "1",
    "ratingCount": "8"
},
"Timings": {
    "cookTime": "PT5M",
    "prepTime": "PT5M",
    "totalTime": "PT10M"
},
"Author": {
    "eval": false,
    "value": "dfgkkdfgdfgfmes",
    "url": "https://www.example.com/",
    "additionalInfo": "Recipe from Good Food magazine, ",
    "description": "Substitute potatoes with pulses for a healthy alternative mash with a chunky texture",
    "published": "November 2011"
},
"Publication": {
    "eval": false,
    "value": "",
    "url": "",
    "additionalInfo": "",
    "published": ""
},
"Nutrition": "per serving",
"NutritionContents": {
    "kcal": "183",
    "fat": "5g",
    "saturates": "1g",
    "carbs": "25g",
    "sugars": "3g",
    "fibre": "7g",
    "protein": "11g",
    "salt": "0.84g"
},
"SkillLevel": "Easy",
"Ingredients": [
   "drizzle", "Asparagus" , "Asparagus" , "Asparagus" , "Asparagus" , "Asparagus" , "Asparagus" , "Asparagus" , "Asparagus" , "Asparagus" 

 ],
"MakingMethod": [
    "Heat the oil in a large saucepan. Add the beans and cook for 3-4 mins until hot through. Lightly mash with a potato masher for a chunky texture. Stir through the pesto and season. To serve, drizzle with a little olive oil, if you like."
],
"Keywords": [
    "Cannellini bean",
    "Cannellini beans",
    "Mash",
    "Beans",
    "Super healthy",
    "Pulses",
    "5-a-day",
    "Low fat",
    "Diet",
    "Dieting",
    "Side dish",
    "Bangers and mash",
    "Sausage and mash",
    "Texture",
    "Fireworks",
    "Pesto",
    "Easy",
    "Vegetarian",
    "Healthy",
    "Bonfire Night"
],
"Category": [
    "Side dish",
    "Dinner"
],
"Cousine": "British",
"Servings": "Serves 4"

}

【问题讨论】:

    标签: elasticsearch elasticsearch-aggregation kibana-7


    【解决方案1】:

    没有简单的方法可以做到这一点。

    选项 1

    在您应用了正确分析器的text 字段上启用fielddata。像这样的:

    {
      "settings": {
        "analysis": {
          "filter": {
            "english_stop": {
              "type":       "stop",
              "stopwords":  "_english_" 
            }
          },
          "analyzer": {
            "rebuilt_stop": {
              "filter": [
                  "asciifolding",
                  "lowercase",
                  "english_stop"
                ],
                "tokenizer": "standard"
            }
          }
        }
      },
      "mappings": {
        "properties": {
            "Ingredients": {
                "type": "text",
                "analyzer": "rebuilt_stop",
                "fielddata": true
            }
        }
      }
    }
    

    然后运行 ​​terms 聚合。 缺点:可以使用a lot of memory because of fielddata usage

    选项 2

    使用term vectors API。由于您对Ingredients 字段中最常用的“值”/“术语”感兴趣,因此您可以在索引中的一个文档上调用此 API,并获得该特定文档中每个术语的总术语频率。缺点:您需要指定某个文档 ID,并且只会报告该文档中的术语。

    类似这样的:

    GET /test/_termvectors/1
    {
      "fields" : ["Ingredients"],
      "offsets" : false,
      "payloads" : false,
      "positions" : false,
      "term_statistics" : true,
      "field_statistics" : false
    }
    

    选项 3

    可能是最丑的。围绕这些行:Elasticsearch: index a field with keyword tokenizer but without stopwords

    优点:不使用fielddata(堆内存)。缺点:您必须在 char_filter 定义中手动定义停用词。

    【讨论】:

    • 请发布您的索引的确切映射 (GET /your_index_name)。
    • 我怀疑:您的Ingredients 字段上没有设置分析器:"Ingredients" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } }, "fielddata" : true}。看看我在答案中的映射,看看应该如何在你的索引中设置分析器。您需要使用更新后的映射创建一个新索引,再次索引文档并再试一次。
    • 如果我在使用您的索引后创建索引,它创建的结果与我已经发布的结果相同。我需要对其执行任何其他任务吗?
    • 那你一定是做错了什么……你测试过我的准确索引了吗?您使用了哪些样本数据?
    • 什么停用词没有被删除?
    猜你喜欢
    • 2017-10-18
    • 1970-01-01
    • 1970-01-01
    • 2017-09-08
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多