Elasticsearch实现复合查询以及mysql like查询实现

Elasticsearch实现复合查询以及mysql like查询实现

不多说了,都是坑,踩爆我了,直接撸方法

需求

我要时间关键字one搜索,索引type里面包含有如下关键字:iphonex,test one等文档
再如,我要搜索一个,文档中字段有类似如下的内容:一个很好的一口好吃的结果都会搜索出来,关键字一个被分词了,所以都搜索出来的
此时我们只想简简单单单单纯纯的搜索出包含一个的关键字文档出来而已,只想简简单单的。。。。

案例

好勒,条件如下,拿过去用吧

{
    "query":{
        "bool":{
            "should":[
                {
                    "match":{
                        "title":{
                            "query":"one",
                            "type":"phrase"
                        }
                    }
                },
                {
                    "wildcard":{
                        "title":"*one*"
                    }
                }
            ],
            "minimum_should_match":"50%",
            "must":[
                {
                    "match":{
                        "state":1
                    }
                },
                {
                    "terms":{
                        "type":[
                            1,
                            2
                        ]
                    }
                },
                {
                    "range":{
                        "start_time":{
                            "gte":"2018-12-04 16:24:06"
                        }
                    }
                }
            ]
        }
    },
    "sort":{
        "id":{
            "order":"desc"
        }
    }
}

案例说明

"should":[
        {
             "match":{
                 "title":{
                     "query":"one",
                     "type":"phrase"
                 }
             }
         },
         {
             "wildcard":{
                 "title":"*one*"
             }
         }
     ],
     "minimum_should_match":"50%",

对于关键词模糊搜索我选用了should类似mysql的or,进行关键词搜索以及wildcard模式进行左右*匹配搜索
最开始我在match的时候出现了文章开始出现的问题 ,后来也是度娘了需求,虽然那啥,我明白是什么问题,但是从了解到使用es不到两天,不过还在搞出来了,有两种方法不让一个被拆分搜索匹配:

方法一

"match_phrase" : {
	"title": { "query": "一个", "slop": 2} }
}

slop值设置在搜索关键字被拆分搜索时,多个关键字间隔多少个其他字符从可以被匹配

方法二

"match":{
  "title":{
       "query":"one",
       "type":"phrase"
   }
}

加入匹配类型"type":"phrase",因此关键词可以进行整词搜索不被切开了(蛋疼)。

注意事项
在用了should之后我用了"minimum_should_match":"50%",条件,看到没,不加这货的话,复合查询的时候should里面关键字搜索不到结果其他的包含关键字的也可能会被搜出来的,should本来就是or,可有可无咯。。。
"minimum_should_match":"50%",必须放在should之后挨着放,别放错位置了,50%至少满足should里面50%条件的结果就匹配出来,当然不满足里面关键字条件的,肯定是不会出来的(?这句话就别放心上了 )

range时间筛选

"range":{
  "start_time":{
       "gte":"2018-12-04 16:24:06"
   }
}
范围操作符包含:

gt :: 大于
gte:: 大于等于
lt :: 小于
lte:: 小于等于

需要支持这样的通过时间进行筛选的话,需要对start_time字段进行mapping设置格式才可以这样用,怎么设置点击Elasticsearch根据日期(年-月-日 时:分:秒)进行range(时间范围筛选)

结束
因为是复合查询,因此should实现了like之后其他条件就得must(实现and)去搞定了
结束了,实践一点,就写一点笔记

Elasticsearch实现MySQL的子查询可以使用Nested类型或者Join类型来实现。具体实现步骤如下: 1. 使用Nested类型实现查询 Nested类型是一种特殊的数据类型,它允许嵌套文档类型的结构。在Elasticsearch中,可以使用Nested类型来实现MySQL的子查询,具体步骤如下: - 创建索引时,将需要嵌套的字段设置为Nested类型; - 在查询时,使用Nested查询查询嵌套的文档。 例如,如果我们要查询一个用户的所有订单信息,并且订单信息中包含了商品信息,可以将订单信息设置为Nested类型,然后使用Nested查询查询订单信息。具体实现代码如下: ``` PUT /my_index { "mappings": { "properties": { "user_id": { "type": "integer" }, "orders": { "type": "nested", "properties": { "order_id": { "type": "integer" }, "order_date": { "type": "date" }, "products": { "type": "nested", "properties": { "product_id": { "type": "integer" }, "product_name": { "type": "text" } } } } } } } } POST /my_index/_doc { "user_id": 1, "orders": [ { "order_id": 1, "order_date": "2021-05-01", "products": [ { "product_id": 1, "product_name": "product1" }, { "product_id": 2, "product_name": "product2" } ] }, { "order_id": 2, "order_date": "2021-05-02", "products": [ { "product_id": 3, "product_name": "product3" }, { "product_id": 4, "product_name": "product4" } ] } ] } POST /my_index/_search { "query": { "nested": { "path": "orders", "query": { "bool": { "must": [ { "match": { "orders.order_id": 1 } }, { "nested": { "path": "orders.products", "query": { "match": { "orders.products.product_name": "product1" } } } } ] } } } } } ``` 2. 使用Join类型实现查询 Join类型是一种特殊的数据类型,它允许在一个文档中引用另一个文档。在Elasticsearch中,可以使用Join类型来实现MySQL的子查询,具体步骤如下: - 创建两个索引,分别存储父文档和子文档; - 在父文档中创建Join字段,并使用Routing来关联子文档; - 在查询时,使用HasChild查询查询子文档。 例如,如果我们要查询一个用户的所有订单信息,并且订单信息中包含了商品信息,可以将订单信息存储在子文档中,然后使用Join类型来关联父文档和子文档,具体实现代码如下: ``` PUT /my_index { "mappings": { "properties": { "user_id": { "type": "integer" }, "order_join": { "type": "join", "relations": { "user": "order" } } } } } PUT /my_index/_doc/1?routing=1 { "user_id": 1, "order_join": { "name": "user", "parent": null } } PUT /my_index/_doc/2?routing=1 { "order_id": 1, "order_date": "2021-05-01", "user_id": 1, "order_join": { "name": "order", "parent": "1" }, "products": [ { "product_id": 1, "product_name": "product1" }, { "product_id": 2, "product_name": "product2" } ] } PUT /my_index/_doc/3?routing=1 { "order_id": 2, "order_date": "2021-05-02", "user_id": 1, "order_join": { "name": "order", "parent": "1" }, "products": [ { "product_id": 3, "product_name": "product3" }, { "product_id": 4, "product_name": "product4" } ] } POST /my_index/_search { "query": { "has_child": { "type": "order", "query": { "bool": { "must": [ { "match": { "order_id": 1 } }, { "has_child": { "type": "product", "query": { "match": { "product_name": "product1" } } } } ] } } } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值