为公司开发搜索功能的时候使用到了阿里的开放搜索,是使用的python,官方没有sdk,只能自己实现api
这里把一些成熟的代码放上来,就是些简单的功能,包括:
1、文档增删改(dealDocPost)
2、post查询(sendQuery)
3、下拉提示(suggest)
4、生成签名(getSignature)
5、get查询(dealDocGet)
URL = 'http://opensearch-cn-hangzhou.aliyuncs.com/index/doc/'
SEARCH_URL = 'http://opensearch-cn-hangzhou.aliyuncs.com/search'
ACCESSKEY_ID = 自己的ID
ACCESSKEY_SECRET = 自己的密码
table = helloworld
app = helloworld
suggest_name = 'helloworld_rule' # 下拉查询规则
suggest_hit = 5
query_hit = 20
action = 'push'
def dealDocPost(items): """post请求,增加,删除,修改,都可以从这里,唯一需要变化的是action""" if not items: return json.dumps({'status':'OK'}) curtime = int(time.time()) SignatureNonce = curtime + random.randrange(1000, 9999) timeStamp = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") params = [ ('AccessKeyId', ACCESSKEY_ID), ('SignatureMethod', 'HMAC-SHA1'), ('SignatureNonce', SignatureNonce), ('SignatureVersion', '1.0'), ('Version', 'v2'), ('Timestamp', timeStamp), ('action', action), ('table_name', table), ('items', json.dumps(items))] signature = getSignature(params= sorted(params, key=lambda x: x[0]) , method= 'POST') result_url = URL+ app + '?' + urllib.urlencode(params[:-3]) +'&Signature=' + signature req = urllib2.Request(result_url) req.add_data('&'.join([urllib.quote(str(k)) + '=' + urllib.quote(str(v)) for k, v in params[-3:]])) result_josnstr = urllib2.urlopen(req).read() print result_josnstr return result_josnstr
def sendQuery(request_data):
# 这里是查询:
query_data = {}
start =
int
(request_data.get(
'start'
,
0
)) hit =
int
(request_data.get(
'hit'
, query_hit)) query = request_data.get(
'query'
) key_words = request_data.get(
'search_text'
) config =
u"start:%d,hit:%d,format:json"
%(start, hit) query = query
or
(
u"default:"
+
u'&'
.join([
u"'%s'"
% kk
for
kk
in
key_words.split()]))
condition =
u"config=%s&&query=%s"
% (config, query) query_data[
'query'
] = condition
if
request_data.get(
'fields'
): query_data[
'fields'
] = request_data.get(
'fields'
) query_data[
'index_name'
] = app
# summary = u'summary_snipped:3,summary_field:content,summary_len:100;summary_snipped:1,summary_field:title,summary_len:50'
result = doc_search(**query_data)
return
result
def doc_search(query, fields = None, summary = None, formula_name = None, first_formula_name = None, index_name = None):
"""
搜索查询
:param query : 搜索主体,包含所有的查询条件。子句分别包含config子句、query子句、sort子句、filter子句、aggregate子句、distinct子句等。
:param fields : 如果指定了此参数,则服务返回的数据集结构只包含fetch_fields里边指定的field,指定多个field可以使用“;”分隔。
:param summary : 动态摘要的配置,可以指定某些字段的飘红、截断等操作。
:param formula_name : 用户指定的精排表达式名称,搜索会获取您在网站中定义的此名称的表达式,并根据此来搜索。
:param first_formula_name : 用户指定的粗排表达式名称,搜索会获取您在网站中定义的此名称的表达式,并根据此来搜索。
:param index_name : 用户要查询的应用名称,需为UTF-8编码的urlencode结果,多应用查询可以使用“;”分隔。
:return :
"""
curtime = int(time.time())
SignatureNonce = curtime + random.randrange(1000, 9999)
timeStamp = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
params = [ ('Version', 'v2'), ('AccessKeyId', ACCESSKEY_ID), ('SignatureMethod', 'HMAC-SHA1'),
('SignatureVersion', '1.0'), ('SignatureNonce', SignatureNonce),
('Timestamp', timeStamp), ('query', query.encode('utf8')),
('index_name', index_name), ('format', 'json')]
# 其他搜索条件
if fields : params.append(('fetch_fields', fields))
if summary : params.append(('summary', summary))
if formula_name : params.append(('formula_name', formula_name))
if first_formula_name : params.append(('first_formula_name', first_formula_name))
signature = getSignature(params = sorted(params, key=lambda x : x[0]) , method='GET')
req = urllib2.Request(SEARCH_URL + '?' + urllib.urlencode(params) + '&Signature=' + signature)
try:
return json.loads(urllib2.urlopen(req).read())
except Exception, e:
return None
def
suggest(query):
'''
用户输入数据获取下列列表提示
:return
:
'''
query = query.encode(
'utf8'
) curtime =
int
(time.time() *
1000000
) SignatureNonce = curtime + random.randrange(
1
,
9999
) timeStamp = datetime.datetime.utcnow().strftime(
"%Y-%m-%dT%H:%M:%SZ"
) params = [ (
'AccessKeyId'
, ACCESSKEY_ID),(
'SignatureMethod'
,
'HMAC-SHA1'
), (
'SignatureNonce'
, SignatureNonce),(
'SignatureVersion'
,
'1.0'
), (
'Version'
,
'v2'
),(
'Timestamp'
, timeStamp), (
'index_name'
, app),(
'suggest_name'
, suggest_name), (
'hit'
, suggest_hit),(
'query'
, query)] signature = getSignature(
params
=
sorted
(params,
key
=
lambda
x: x[
0
]) ,
method
=
'GET'
) result_url =
'http://opensearch-cn-hangzhou.aliyuncs.com/suggest?'
+urllib.urlencode(params)+
'&Signature='
+ signature req = urllib2.Request(result_url) res_data = urllib2.urlopen(req) res =
eval
(res_data.read())
return
res
def getSignature(params, method='GET'):
"""生成签名
. 参考文档:http://help.opensearch.aliyun.com/index.php?title=%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6#.E7.AD.BE.E5.90.8D.E7.94.9F.E6.88.90.E6.96.B9.E6.B3.95
"""
str_params = '&'.join([urllib.quote(str(k)) + '=' + urllib.quote(str(v)) for k, v in params])
str_params = str_params.replace('%7E', '~')
str_params = method + '&%2F&' + urllib.quote(str_params)
StringToSign = str_params.replace('%7E', '~')
# 生成签名
signature = base64.b64encode(hmac.new('%s&' % ACCESSKEY_SECRET, StringToSign, digestmod = hashlib.sha1).digest())
return urllib.quote(signature)
def formatItem(dict_list, cmd='add'):
insert_items = []
for dict in dict_list:
_dict = {}
略
insert_items.append({ 'cmd' : cmd,
'timestamp' : int(time.time()*1000),
'fields' : _dict
})
return insert_items
def dealDocGet(items):
"""
get请求 (预留方法)
:param items:
:return:
"""
if not items:
return json.dumps({'status':'OK'})
curtime = int(time.time())
SignatureNonce = curtime + random.randrange(1000, 9999)
timeStamp = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
params = [ ('AccessKeyId', ACCESSKEY_ID),
('SignatureMethod', 'HMAC-SHA1'),
('SignatureNonce', SignatureNonce),
('SignatureVersion', '1.0'),
('Version', 'v2'),
('Timestamp', timeStamp),
('action', action),
('table_name', table),
('items', json.dumps(items))]
signature = getSignature(params= sorted(params, key=lambda x: x[0]) , method= 'POST')
result_url = URL+ app + '?' + urllib.urlencode(params[:-3]) +'&Signature=' + signature
req = urllib2.Request(result_url)
req.add_data('&'.join([urllib.quote(str(k)) + '=' + urllib.quote(str(v)) for k, v in params[-3:]]))
print urllib2.urlopen(req).read()
if __name__ == '__main__':
pass