使用ElasticSearch搭建动态排序引擎

本来打算至少一月一更的,结果写完第一篇后爆忙了一段时间(眼神死)...

在这个专栏里,我不会翻译官方文档。所有关于ES本身的介绍,推荐直接看英文版官方文档,或者google之。ES本身以惊人的速度在迭代,现在的中文材料很容易就跟不上最新版的节奏。特别是5.0出来之后,会有非常大的变化。

在这个专栏里,我会根据自己的实战经验,写一下Elastic Search全家桶(官方自称为Elastic Stack)的应用。从年初到现在,我个人也从ES吹,到ES与Sphinx混用,到了自造轮子的阶段。ES很好用,也有坑;ES不仅仅是一个搜索引擎,配合其全家桶,可以干更多事情。我相信,告诉大家ES可以用来干嘛,比起搬运文档要更有价值。

第二篇文章,准备写一下Elastic Search的一个经典、简单的应用场景:动态排序引擎

举个例子,现在你做了一个UGC图床产品,需要将用户最新PO的图按某种顺序(例如时间或热度)排序展示出来。用户发了图之后,在“最新”那一页一刷新,就能看到他/她刚发的图,然后可以一直往下翻。图片可能存在不同的TAG(例如“妹子图”、“无聊图”,甚至做二级的细分)。等等,我才不是在说某网站呢,这是个很常见的需求好么!

如果你用MySQL来实现这个需求,可以是可以。不过,随着图片数量和查询请求的增加,很快就会出现性能瓶颈,产生大量的慢查询。你需要一个高性能动态排序引擎,有以下的功能:

• 动态索引,即可以随时增删查改条目;

• 排序,输入from和size(从哪到哪),根据某个数值(热度或插入时间戳),倒序排序、输出结果;

• Filter,例如根据TAG筛选图片;

假定图片是先存MySQL、再同步去ES。用MySQL存数据和保证原子性,用ES来顶查询请求。在ES里面,你可以这么设计索引结构:

{
    "properties": {
        "id": {
            "type": "long"
        },
        "tags": {
            "type": "string"
        },
        "hot": {
            "type": "double"
        },
        "new": {
            "type": "double"
        },
        "update_time": {
            "type": "date",
            "format": "epoch_second"
        },
        "is_searchable": {
            "type": "short"
        }
    }
}

id:即MySQL的id,使用AUTO_INCREMENT保证唯一性。

tags:即“妹子图”、“无聊图”这样的TAG,空格隔开,确保ES默认分词器可以工作。

hot:热度数据,例如妹子图的OO数量(甚至威尔逊区间啥的)。

new:即上传时间戳。

update_time:等于new。这里是Kibana里看数用的(一定要有个date属性)。

is_searchable:0或1,默认0,1的时候才能被搜出来。用于自动鉴黄、人工去黄啥的。

每次更新数据,同步更新到ES里面,这个需求就做好了。什么,这么简单?是的,二手手游账号买号平台ES把剩下的事情都完成了。

搜的时候这么搜:

{
    "from": ,
    "size": 10,
    "query": {
        "filtered": {
            "query": {
		"bool": {
                    "must": [
                        {
                            "term": {
                                "tags": {
                                    "value": "妹子图"
                                }
                            }
                        }
                    ]
                }
	    },
            "filter": {
                "or": [
                    {
                        "and": [
                            {
			        "term": {
                                    "is_searchable": 1
                                }
                            }
			]
	            }
		]
            }
        }
    },
    "sort": {
        "hot": {
	    "order": "desc"
	}
    }
}

稍微解释一下这个语句。query里面最简单的做法是填入`"match_all": {}`,这样可以搜所有东西出来。filter先一层or再套一层and,是便于扩展的一个写法。

这个语句,可以把TAG=“妹子图”的所有内容,按热度倒序排序(啧啧)。注意,上面的语句并非性能最佳的写法,如果妹子图非常高频,就不应用must query搜索TAG,而是应该用type或者filter来过滤。

这就是我为啥那么喜欢用Elastic Search。ES是动态索引,新插入的数据马上就可以被搜出来;强大的DSL,我能想到的查询基本都能做到。

动态排序引擎这个需求,用ES几下子就能搞定,性能还不差。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值