Yhzhtk's Blog

(热爱技术,高效Code)     归档  标签  源码  关于 


阿里云开放云搜索初探

2013-07-02    云搜索  python 


    前几天申请了阿里云开放云搜索(Aliyun OpenSearch)的邀请码,今早通过收到通过验证了,于是准备试试云搜索

    阿里云搜索使用很简单,和Lucene一样,包括索引文档字段几个概念。每个索引可以当成数据库的一个数据库,一条文档当成数据库的一条记录,一个字段就是数据库的一个字段。

    目前支持四种形式的搜索模板,资讯类,小说类,应用类和社区类。模板在这儿就是规定好了索引的字段,也可以自定义。详细介绍

    我想测试一下,就把自己的博客写的这十几篇POST发上去建立索引吧,使用了资讯类的模板。

模板字段如下:
字段名 类型 字段说明 独立检索 可检索 可排序 可筛选
id STRING 文档标识(必选)      
title TEXT 资讯标题    
body TEXT 资讯内容      
type_id UINT16 类型,如财经      
cat_id UINT16 组别,支持多个,如"cat_id":[12, 13]、"cat_id":["12", "13"],具体请参加模版数据类型说明      
url STRING 展示url        
author TEXT 作者    
thumbnail STRING 缩略图        
source TEXT 新闻来源      
create_timestamp UINT32 创建时间    
update_timestamp UINT32 更新时间    
hit_num UINT32 点击数    
focus_count UINT32 关注数    
grade UINT32 读者评分    
comment_count UINT32 评论数    
boost INT8 站长自定义加分项    
integer_1 UINT32 保留字段,站长自定义    
integer_2 UINT32 保留字段,站长自定义    
integer_3 UINT32 保留字段,站长自定义    
tag TAG 标签      
display_text STRING 站长自定义展示字段        

提供的需要上传的JSON格式示例:

[
    {
        "fields": {
            "body": "广大中小企业都有各种结构化的数据需要进行检索,目前一般采用数据库本身提供的搜索功能或者利用open source的搜索软件搭建", 
            "display_text": "open search", 
            "hit_num": "88888", 
            "update_timestamp": "1345448016", 
            "type_id": "1", 
            "url": "http://www.aliyun.com", 
            "cat_id": [1,2], 
            "author": "阿里云", 
            "grade": "10", 
            "comment_count": "1234", 
            "tag": {"搜索":10,"阿里云":2,"云搜索":5,"开放搜索":8}, 
            "source": "阿里云云搜索", 
            "focus_count": "8888", 
            "title": "阿里云隆重推出开放搜索", 
            "boost": "1", 
            "id": "id_1", 
            "integer_1": "100", 
            "create_timestamp": "1345448016"
        }, 
        "cmd": "ADD"
    }, ...
]

    其中很多字段用不上,可以忽略。我的博客都是在jekyll中的post类型,需要把所有的post转为JSON格式。我写了一个Python,来处理_post文件夹下面的所有文章,最后导出Json

#coding=utf-8
'''
将jekyll中_post目录下的文章到处json格式,用于阿里云搜索
@author: gudaihui
'''

import os
import re
import json
import time

def object2dict(obj):
    '''使用内置json转换时,需要将对象转为dict'''
    #convert object to a dict
    d = {}
    d.update(obj.__dict__)
    return d

class PostInfo():
    '''存储一条博客的所有字段类'''
    def __init__(self, title, tags, content, rooturl, f):
        self.title = title
        self.tag = {}
        #标签有一个权重,默认都为1
        for t in tags.split(","):
            self.tag[t.strip()] = 1
        self.body = content
        self.id = f.replace("-", "").replace(".html", "")
        self.display_text = "open search"
        self.hit_num = "88888"
        #处理日期和URL
        t = re.match('\\d{4}-\\d{2}-\\d{2}', f).group()
        self.url = rooturl + f.replace(t + "-", (t + "-").replace("-", "/"))
        self.update_timestamp = "%d" % time.mktime(time.strptime(t,'%Y-%m-%d'))
        self.create_timestamp = "%d" % time.mktime(time.strptime(t,'%Y-%m-%d'))
        self.type_id = "1"
        self.cat_id= [1,2]
        self.author="yhzhtk"
        self.grade="10"
        self.source="yhzhtk"
        self.boost = "1"

    
def getPostInfo(path, rooturl="http://yhzhtk.info/"):
    '''从文件中读取所有的POST返回PostInfo信息'''
    os.chdir(path)
    posts = [[open(f, "r").read(), f]
             for f in os.listdir(path) if f.endswith(".html")]
    pattern = re.compile(r"---\nlayout: post\ntitle: ([^\n]*)\ntags: \[([^\]]*)\]\n---\n(.*)", re.DOTALL)
    infos = []
    for post, f in posts:
        match = pattern.match(post)
        if match:
            title = match.group(1)
            tags =  match.group(2)
            content = match.group(3)
            content = re.sub("<[^>]*>","",content)
            content = re.sub("{%[^%]*%}","",content)
            content = content.replace("\n", "")
            infos.append(PostInfo(title, tags, content, rooturl, f))
    return infos

def genPostJson(infos):
    '''将PostInfo处理得到最后的Json'''
    jsonstr = ""
    for info in infos:
        temp = json.dumps(info, ensure_ascii=False, default=object2dict)
        temp = '''{"fields":''' + temp + ''', "cmd": "ADD"}'''
        jsonstr += "," + temp
    if json:
        jsonstr = jsonstr[1:]
    jsonstr = "[" + jsonstr + "]"
    print jsonstr

    
if __name__ == '__main__':
    '''开始执行'''
    path = r"C:\Documents and Settings\yicha\blog\_posts"
    infos = getPostInfo(path)
    genPostJson(infos);

    所有的json是直接输出了,也可以输出到一个文件中。然后将文件上传到刚才新建的索引中。刷新,看到文档条数不为0,就可以点击搜索测试了,如果数量仍为0,可以查看错误日志,里面写明了错误的文档和错误原因。最后,可以通过给的API把搜索功能添加到你的产品中。

    搜索的效率问题现在还没法知道,因为文档数比较少。等有机会可以应用到实际中测测。





Load Disqus comments, wait a moment..

分类标签

jekyll3   编码1   windows1   bootstrap1   git3   删除1   命令3   python11   ide1   学习笔记3   实例分析1   mp3-tag1   github1   gravatar1   goagent1   翻墙1   C#4   找茬工具1   微博自动评论1   电脑监控1   备份1   云搜索1   wxPython1   py2exe1   yaml1   Eric1   PyQt1   Django1   设计模式5   翻译4   单例1   工厂1   抽象工厂1   生成器1   原型1   适配器1   桥接1   组合1   装饰1   外观1   享元1   代理1   MVC1   观察者1   状态1   策略1   模板1   访问者1   职责链1   解释器1   迭代器1   中介者1   备忘录1   js1   resize bar1   geohash1   口琴1   rpm安装gitlab1   CentOs1   WordPress1   数据库1   读脏数据1   丢失的修改1   不可重复读1   幻影读1   1   隔离1   思维导图1   事务1   笔记迁移1   note1   issue1  

最新博文

最新评论

Feed订阅


©2013 首页   关于     View me on GitHub Powered by Jekyll & Bootstrap 知识共享许可协议