在 Python 中执行异步的 Solr 查询

我经常需要用Python与solr进行异步请求工作。这里有段代码阻塞在Solr http请求上, 直到第一个完成才会执行第二个请求,代码如下:

01 import requests
02  
03 #Search 1
04 solrResp = requests.get('http://mysolr.com/solr/statedecoded/search?q=law')
05  
06 for doc in solrResp.json()['response']['docs']:
07     print doc['catch_line']
08  
09 #Search 2
10 solrResp = requests.get('http://mysolr.com/solr/statedecoded/search?q=shoplifting')
11  
12 for doc in solrResp.json()['response']['docs']:
13     print doc['catch_line']

(我们用Requests库进行http请求)

通过脚本把文档索引到Solr, 进而可以并行工作是很好的。我需要扩展我的工作,因此索引瓶颈是Solr,而不是网络请求。

不幸的是,当进行异步编程时python不像Javascript或Go那样方便。但是,gevent库能给我们带来些帮助。gevent底层用的是libevent库,构建于原生异步调用(select, poll等原始异步调用),libevent很好的协调很多低层的异步功能。

使用gevent很简单,让人纠结的一点就是thegevent.monkey.patch_all(), 为更好的与gevent的异步协作,它修补了很多标准库。听起来很恐怖,但是我还没有在使用这个补丁实现时遇到 问题。

事不宜迟,下面就是你如果用gevents来并行Solr请求:

01 import requests
02 from gevent import monkey
03 import gevent
04 monkey.patch_all()
05  
06  
07 class Searcher(object):
08     """ Simple wrapper for doing a search and collecting the
09         results """
10     def __init__(self, searchUrl):
11         self.searchUrl = searchUrl
12  
13     def search(self):
14         solrResp = requests.get(self.searchUrl)
15         self.docs = solrResp.json()['response']['docs']
16  
17  
18 def searchMultiple(urls):
19     """ Use gevent to execute the passed in urls;
20         dump the results"""
21     searchers = [Searcher(url) for url in urls]
22  
23     # Gather a handle for each task
24     handles = []
25     for searcher in searchers:
26         handles.append(gevent.spawn(searcher.search))
27  
28     # Block until all work is done
29     gevent.joinall(handles)
30  
31     # Dump the results
32     for searcher in searchers:
33         print "Search Results for %s" % searcher.searchUrl
34         for doc in searcher.docs:
35             print doc['catch_line']
36  
37 searchUrls =['http://mysolr.com/solr/statedecoded/search?q=law',
38               'http://mysolr.com/solr/statedecoded/search?q=shoplifting']
39  
40 searchMultiple(searchUrls)
代码增加了,而且不如相同功能的Javascript代码简洁,但是它能完成相应的工作,代码的精髓是下面几行:
1 # Gather a handle for each task
2 handles = []
3 for searcher in searchers:
4     handles.append(gevent.spawn(searcher.search))
5  
6 # Block until all work is done
7 gevent.joinall(handles)
我们让gevent产生searcher.search, 我们可以对产生的任务进行操作,然后我们可以随意的等着所有产生的任务完成,最后导出结果。

差不多就这样子.如果你有任何想法请给我们留言。让我们知道我们如何能为你的Solr搜索应用提供帮助。

你可能感兴趣的:(工作,python,索引,异步,Solr)