我在弹性搜索中使用了multi_match查询,因为我只对3个字段感兴趣。
query: {
filtered: {
query: {
multi_match: {
fields: ['subject', 'text', 'task_comments.text'],
query: USER_INPUT
}
}
}
}
如果我搜索Apple TV,我会收到“Apple TV”,Apple和TV的结果。
我希望用户根据他们的输入选择搜索完全匹配。因此,如果他们搜索“Apple TV”(带双引号),它应该只返回包含“Apple TV”的结果。不应返回仅包含Apple的结果。
是否可以仅使用弹性搜索执行此操作?
或者我是否需要根据用户的输入更改应用程序生成的查询?
答案 0 :(得分:1)
您可以将索引设置为也包含" raw"对于您要搜索的每个字段,未分析sub-field。
作为一个玩具示例,我设置了一个简单的索引,并添加了一些文档:
PUT /test_index
{
"mappings": {
"doc":{
"properties": {
"text_field": {
"type": "string",
"analyzer": "standard",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}
POST /test_index/doc/_bulk
{"index":{"_id":1}}
{"text_field": "Apple TV"}
{"index":{"_id":2}}
{"text_field": "Apple iPhone"}
{"index":{"_id":3}}
{"text_field": "Apple MacBook"}
此索引使用standard analyzer作为主要字段(指定它是多余的,因为它是默认值,但我想明确它),并且根本没有分析器用于子字段。
因此,如果我搜索主要字段,我会收到所有三个文档:
POST /test_index/_search
{
"query": {
"match": {
"text_field": "Apple TV"
}
}
}
...
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 0.98479235,
"hits": [
{
"_index": "test_index",
"_type": "doc",
"_id": "1",
"_score": 0.98479235,
"_source": {
"text_field": "Apple TV"
}
},
{
"_index": "test_index",
"_type": "doc",
"_id": "2",
"_score": 0.10063131,
"_source": {
"text_field": "Apple iPhone"
}
},
{
"_index": "test_index",
"_type": "doc",
"_id": "3",
"_score": 0.10063131,
"_source": {
"text_field": "Apple MacBook"
}
}
]
}
}
但如果我搜索" raw"子领域,我只回到一个文档:
POST /test_index/_search
{
"query": {
"match": {
"text_field.raw": "Apple TV"
}
}
}
...
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1.4054651,
"hits": [
{
"_index": "test_index",
"_type": "doc",
"_id": "1",
"_score": 1.4054651,
"_source": {
"text_field": "Apple TV"
}
}
]
}
}
您应该可以为每个字段执行此操作,以使其与multi_match
查询一起使用。或者,您可以使用_all field进行设置,然后只对其使用"match"
查询。
以下是一个地方的代码:
http://sense.qbox.io/gist/31ff17997b4971b6515f019ab514f9a17da1a606