巡风源码阅读与分析--querylogic函数
文件位置:views/lib/QueryLogic.py
Querylogic()
# 搜索逻辑 def querylogic(list): query = {} if len(list) > 1 or len(list[0].split(':')) > 1: for _ in list: if _.find(':') > -1: q_key, q_value = _.split(':', 1) if q_key == 'port': query['port'] = int(q_value) elif q_key == 'banner': zhPattern = re.compile(u'[\u4e00-\u9fa5]+') contents = q_value match = zhPattern.search(contents) # 如果没有中文用全文索引 if match: query['banner'] = {"$regex": q_value, '$options': 'i'} else: text_query = mgo_text_split(q_value) query['$text'] = {'$search': text_query, '$caseSensitive':True} elif q_key == 'ip': query['ip'] = {"$regex": q_value} elif q_key == 'server': query['server'] = q_value.lower() elif q_key == 'title': query['webinfo.title'] = {"$regex": q_value, '$options': 'i'} elif q_key == 'tag': query['webinfo.tag'] = q_value.lower() elif q_key == 'hostname': query['hostname'] = {"$regex": q_value, '$options': 'i'} elif q_key == 'all': filter_lst = [] for i in ('ip', 'banner', 'port', 'time', 'webinfo.tag', 'webinfo.title', 'server', 'hostname'): filter_lst.append({i: {"$regex": q_value, '$options': 'i'}}) query['$or'] = filter_lst else: query[q_key] = q_value else: filter_lst = [] for i in ('ip', 'banner', 'port', 'time', 'webinfo.tag', 'webinfo.title', 'server', 'hostname'): filter_lst.append({i: {"$regex": list[0], '$options': 'i'}}) query['$or'] = filter_lst return query
传过来的是一个列表
我们先看列表长度为1,而且没有“:”的情况:
else: filter_lst = [] for i in ('ip', 'banner', 'port', 'time', 'webinfo.tag', 'webinfo.title', 'server', 'hostname'): filter_lst.append({i: {"$regex": list[0], '$options': 'i'}}) query['$or'] = filter_lst
返回一个对象,类似这样的: {'$or': [{'ip': {'$options': 'i', '$regex': '127.0.0.1'}},....]}将数组中这些值构造成上面的形式,然后用’$or’ 不难猜测是要将条件代入查询,用or来连接。
再看列表长度不为1,或者有“:”的情况:
for _ in list: if _.find(':') > -1:
遍历列表,找到有“:”的情况。 然后分割 ,如果是查port就转为整型。 查banner的话,先判断是否存在中文,如果有中文就构造成
{'banner': {'$options': 'i', '$regex': u'\u963f\u8428\u5fb7aaa'}} 这样的,代入查询。
没有中文的话:mgo_text_split()这个函数:
def mgo_text_split(query_text): ''' split text to support mongodb $text match on a phrase ''' sep = r'[`\-=~!@#$%^&*()_+\[\]{};\'\\:"|<,./<>?]' word_lst = re.split(sep, query_text) text_query = ' '.join('\"{}\"'.format(w) for w in word_lst) return text_query
先按这些特殊符号分割,然后连接成一个字符串 ”xxx” “xxx” “xxx”。
text_query = ' '.join('\"{}\"'.format(w) for w in word_lst)
这句可以看成:
L =[] for w in word_lst: L.append('\"{}\"'.format(w)) text_query = ' '.join(L)
然后构造成这样:{'$text': {'$caseSensitive': True, '$search': '"xxx" "xxx" "xxx"'}}代入查询。
下面代码均一样。
最后else 就是q_key都没有定义的话,就是{'key':’value’}
$regex 是利用正则查询 $options 等于 i 则是不区分大小写。
$search 文本索引查询 。$caseSensitive 是否区分大小写。
这些MongoDB的条件,在这篇博客均有。
https://blog.csdn.net/qq_16313365/article/details/58599253
总得来说这个函数就是将搜索的值转成mongoDB能查询的语句。