term
查询对于查找单个值非常有用,但通常我们可能想搜索多个值。 如果我们想要查找价格字段值为 $20 或 $30 的文档该如何处理呢?
不需要使用多个 term
查询,我们只要用单个 terms
查询(注意末尾的 s ), terms
查询好比是 term
查询的复数形式(以英语名词的单复数做比)。
它几乎与 term
的使用方式一模一样,与指定单个价格不同,我们只要将 term
字段的值改为数组即可:
{
"terms" : {
"price" : [20, 30]
}
}
与 term
查询一样,也需要将其置入 filter
语句的常量评分查询中使用:
GET /my_store/products/_search
{
"query" : {
"constant_score" : {
"filter" : {
"terms" : { 1
"price" : [20, 30]
}
}
}
}
}
1 这个 terms 查询被置于 constant_score 查询中
运行结果返回第二、第三和第四个文档:
"hits" : [
{
"_id" : "2",
"_score" : 1.0,
"_source" : {
"price" : 20,
"productID" : "KDKE-B-9947-#kL5"
}
},
{
"_id" : "3",
"_score" : 1.0,
"_source" : {
"price" : 30,
"productID" : "JODL-X-1937-#pV7"
}
},
{
"_id": "4",
"_score": 1.0,
"_source": {
"price": 30,
"productID": "QQPX-R-3956-#aD8"
}
}
]
一定要了解 term
和 terms
是 包含(contains) 操作,而非 等值(equals) (判断)。 如何理解这句话呢?
如果我们有一个 term(词项)过滤器 { "term" : { "tags" : "search" } }
,它会与以下两个文档 同时 匹配:
{ "tags" : ["search"] }
{ "tags" : ["search", "open_source"] } 1
1 尽管第二个文档包含除 search 以外的其他词,它还是被匹配并作为结果返回。
假设有
{ "tags" : ["search"] }
{ "tags" : ["search", "open_source"] }
两个文档,{ "term" : { "tags" : "search" } }都能匹配,但想只搜索包含一个的值,怎么办?
插入数据时多加一个长度字段:
{ "tags" : ["search"], "tag_count" : 1 }
{ "tags" : ["search", "open_source"], "tag_count" : 2 }
查找时加上tag_count精确查找即可。
如果一定期望得到我们前面说的那种行为(即整个字段完全相等),最好的方式是增加并索引另一个字段, 这个字段用以存储该字段包含词项的数量,同样以上面提到的两个文档为例,现在我们包括了一个维护标签数的新字段:
{ "tags" : ["search"], "tag_count" : 1 }
{ "tags" : ["search", "open_source"], "tag_count" : 2 }
一旦增加这个用来索引项 term 数目信息的字段,我们就可以构造一个 constant_score
查询,来确保结果中的文档所包含的词项数量与要求是一致的:
GET /my_index/my_type/_search
{
"query": {
"constant_score" : {
"filter" : {
"bool" : {
"must" : [
{ "term" : { "tags" : "search" } }, 1
{ "term" : { "tag_count" : 1 } } 2
]
}
}
}
}
}
1 查找所有包含 term search 的文档。
2 确保文档只有一个标签。
这个查询现在只会匹配具有单个标签 search 的文档,而不是任意一个包含 search 的文档