我是Elasticsearch的新手,我必须执行以下查询:
GET book-lists/book-list/_search
{
"query":{
"filtered":{
"filter":{
"bool":{
"must":[
{
"term":{
"title":"Sociology"
}
},
{
"term":{
"idOwner":"17xxxxxxxxxxxx45"
}
}
]
}
}
}
}
}
根据Elasticsearch API,它等同于伪SQL:
SELECT document
FROM book-lists
WHERE title = "Sociology"
AND idOwner = 17xxxxxxxxxxxx45
问题是我的文档看起来像这样:
{
"_index":"book-lists",
"_type":"book-list",
"_id":"AVBRSvHIXb7carZwcePS",
"_version":1,
"_score":1,
"_source":{
"title":"Sociology",
"books":[
{
"title":"The Tipping Point: How Little Things Can Make a Big Difference",
"isRead":true,
"summary":"lorem ipsum",
"rating":3.5
}
],
"numberViews":0,
"idOwner":"17xxxxxxxxxxxx45"
}
}
上面的Elasticsearch查询并没有返回任何内容。
然而,此查询返回上面的文档:
GET book-lists/book-list/_search
{
"query":{
"filtered":{
"filter":{
"bool":{
"must":[
{
"term":{
"numberViews":"0"
}
},
{
"term":{
"idOwner":"17xxxxxxxxxxxx45"
}
}
]
}
}
}
}
}
这让我怀疑" title"两个字段的名称相同是为了什么。
有没有办法解决这个问题,而无需重命名任何字段。或者我在其他地方错过了它?
感谢任何想要帮助的人。
答案 0 :(得分:11)
您的问题已在in the documentation中说明。
我怀疑您的索引没有任何显式映射,这意味着elasticsearch将使用动态映射。
对于字符串字段,它会将字符串传递给standard analyzer,这会降低字符串(除其他外)。这就是您的查询不起作用的原因。
您的选择是:
index: not_analyzed
)之前不对其进行分析。query_string
代替term
,它将在运行之前分析查询。)查看您存储的数据类型,您可能需要指定显式的not_analyzed
映射。
对于选项三,您的查询将如下所示:
{
"query":{
"filtered":{
"filter":{
"bool":{
"must":[
{
"query_string":{
"fields": ["title"],
"analyzer": "standard",
"query": "Sociology"
}
},
{
"term":{
"idOwner":"17xxxxxxxxxxxx45"
}
}
]
}
}
}
}
}
请注意,query_string查询具有特殊语法(例如,OR和AND不被视为文字),这意味着您必须小心提供它。因此,使用术语过滤器进行显式映射可能更适合您的用例。
答案 1 :(得分:1)
要扩展solarissmoke的解决方案,而该字段的内容将通过标准分析器,您的查询将不会。如果您在术语查询中引用Elasticsearch文档,您将看到未分析术语查询。
匹配查询可能更适合您的情况。默认情况下,您将以与标题字段内容相同的方式分析您查询的内容。 query_string查询为表格带来了更多内容,如果您打算使用它,则应查看文档。
所以再次使用小调整你的内容:
GET book-lists/book-list/_search
{
"query":{
"filtered":{
"filter":{
"bool":{
"must":[
{
"match":{
"title":"Sociology"
}
},
{
"term":{
"idOwner":"17xxxxxxxxxxxx45"
}
}
]
}
}
}
}
}
重要的是要注意将术语小写版本传递给术语查询(hack - 看起来似乎不是一个好主意,因为solarissmoke描述了标准分析器的其他功能,如停止过滤器),使用query_string查询,或使用匹配查询仍然与您描述的SQL查询非常不同:
SELECT document
FROM book-lists
WHERE title = "Sociology"
AND idOwner = 17xxxxxxxxxxxx45
使用这些Elasticsearch查询,您可以匹配idOwner可能相同的记录,但标题可能类似于“另一个社会学标题”,这与您对该SQL的期望不同。以下是文档中的一些很棒的内容和另一个stackoverflow文章,它将详细说明发生的事情,术语查询和过滤器是合适的,并获得完全匹配:
Elasticsearch : Finding Exact Values
Stackoverflow : Exact (not substring) matching in Elasticsearch
答案 2 :(得分:1)
我已在此blog中描述了此问题。 问题是由于Elasticsearch中的默认标记化。 同样,我概述了2个解决方案。 一种是在必填字段上启用not_analyzed标志,另一种是使用关键字tokenizer。