众所周知es中有个_all元字段(它包含每个字段的文本副本),使用_all进行搜索的query_string和simple_query_string查询有分词搜索的场景非常好赞,不过从6.0版本已默认禁用(_all不能再为使用Elasticsearch 6.0或更高版本创建的索引配置,更多)。
要查询某个document中_all的信息则可以通过:get product/doc/1?stored_fields=_all,更多
如果你还有一些这样的需求:假如我们要经常对这三个字段进行搜索,那么一种方法我们可以在must子句中使用should子句运行bool查询。这种方法写起来比较麻烦。有没有一种更好的方法呢?
而从6.7开始提供了copy_to来提高搜索的效率,其实它源于_all的。
http://xxxxxx:9200/product_shop_test
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"doc": {
"properties": {
"product_code": {
"type": "keyword",
"copy_to": "product_shop_code"
},
"shop_code": {
"type": "keyword",
"copy_to": "product_shop_code"
},
"product_shop_code": {
"type": "text"
}
}
}
}
}
//_bulk最后回车换行
http://xxxxxx:9200/_bulk
{"index":{"_index":"product_shop_test","_type":"doc","_id":1}}
{"shop_code":"9527","product_code":"8848"}
{"index":{"_index":"product_shop_test","_type":"doc","_id":2}}
{"shop_code":"9527","product_code":"8849"}
http://xxxxxx:9200/product_shop_test/_search
{
"query": {
"match_all": {}
}
}
//返回
{
"took": 0,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1,
"hits": [
{
"_index": "product_shop_test",
"_type": "doc",
"_id": "1",
"_score": 1,
"_source": {
"shop_code": "9527",
"product_code": "8848"
}
},
{
"_index": "product_shop_test",
"_type": "doc",
"_id": "2",
"_score": 1,
"_source": {
"shop_code": "9527",
"product_code": "8849"
}
}
]
}
}
简单的理解,copy_to可以将它们合成一个字段,这样可以方便我们的搜索。
提问及解答环节:
1. product_shop_code好像不在_source中?
没错,它并不存在于我们文档的source里。
2. 怎样查看copy_to的内容?
maping时将store属性为true,通过查看_all的方式一样,get api中参数stored_fields来查看
"product_shop_code": {
"type": "keyword",
"store": true
}
http://xxxxx:9200/product_shop_test1/doc/1?stored_fields=product_shop_code
3. 可以copy_to的目标字段可以指定keyword,不能的话我上述的场景怎么破?
copy_to仅适用于全文搜索,换言之product_shop_code必须指定为text,否则影响该字段功能使用。
不用bool当然也是解的,可以指定minimum_should_match即可
{
"query": {
"match": {
"product_shop_code": {
"query": "9527 8848",
"minimum_should_match": 2
}
}
}
}
好像下面这个也可以
{
"query": {
"match": {
"product_shop_code": {
"query": "9527-8848",
"minimum_should_match": 2
}
}
}
}
没错,你已经发现了问题之所在!要自定义个分词器(可以按空格或业务不会使用的字符),否则又找到的不是你想要的!