Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import re
- import sys
- import json
- from flask import request, abort
- from werkzeug.exceptions import BadRequest
- from gran.main.lib.ext_filter_sql import _validate_crit, extFilterGetSQL, prepareCriteriaSQL, extFilterByRules
- from gran.main.util.crossdomain import crossdomain
- from services import app
- from gran.main.db.open_connection import with_open_connection, build_query, rows_to_dict_list
- @app.route('/entities/search', methods=['GET', 'POST', 'OPTIONS'])
- @crossdomain(origin='*')
- def search_nodes():
- response = {}
- try:
- search_string = request.get_json()['search_string'].strip()
- result = re.split(r'\s', search_string)
- full_json = request.get_json()
- ext_filter = full_json.get('criteria')
- tags = []
- if ext_filter != []:
- tags = ext_filter['tags']
- tags = [int(tag) for tag in tags]
- data = search_result_in_db(result, tags, ext_filter)
- response['errorcode'] = 0
- response['errordesc'] = ''
- response['data'] = data
- except BadRequest:
- abort(422)
- except ValueError:
- abort(422)
- except TypeError:
- abort(422)
- except Exception as e:
- response['errorcode'] = 1
- response['errordesc'] = str(e)
- response['data'] = []
- return response, 200
- def _prepare_criteria_sql(criteria):
- if criteria is None or criteria == []:
- return '', []
- else:
- criteria_sql = ''
- criteria_data = []
- criteria_sql,criteria_data = prepareCriteriaSQL(criteria)
- criteria_sql = ' JOIN ('+criteria_sql+') tblCrit ON tblCrit.id=entities.id '
- return criteria_sql, criteria_data
- def gen_all_ngrams(search_list):
- search_clear = [elem for elem in search_list if elem != '']
- if len(search_clear) == 0:
- return []
- if len(search_clear)>1 and sys.getsizeof(' '.join(search_clear)) < 256:
- ngram_range = [1, len(search_clear)]
- else:
- ngram_range = [1]
- return [list(zip(*[search_clear[i:] for i in range(n)])) for n in ngram_range]
- def gen_sql_var(comb_list):
- if len(comb_list) == 0:
- return [['1=1'], ['1=1'], ['1'], ['']]
- condSQLcontent = 'CONTAINS(CONTENT3, %s, {}) > 0'
- condSQLname = 'CONTAINS(name, %s, {}) > 0'
- # orderSQL = 'SCORE({})/COALESCE(NULLIF(SCORE({}),0),1)'
- orderSQL = 'SCORE({})'
- orderData = []
- indexCont = []
- indexName = []
- stringData = []
- for i, temp_list in enumerate(comb_list):
- base_comb = [' ACCUM '.join(['%{' + ' '.join(content) + '}%' for content in temp_list])]
- base_comb += [' ACCUM '.join(['{' + ' '.join(content) + '}'for content in temp_list])]
- tempOrder = []
- tempCont = []
- tempName = []
- for j, content in enumerate(base_comb):
- tempOrder += [str(10**j)+'*'+orderSQL.format(j + 1)]
- tempCont += [condSQLcontent.format(j + 1)]
- tempName += [condSQLname.format(j + 1)]
- indexCont += [' OR '.join(tempCont)]
- indexName += [' OR '.join(tempName)]
- orderData += [str(10 ** (i)) + '*' + '(' + ' + '.join(tempOrder) + ')']
- stringData += base_comb
- return [indexCont, indexName, orderData, stringData]
- @with_open_connection
- def search_result_in_db(search_string, tags, ext_filter, cursor):
- rows = []
- if len(search_string) == 1 and search_string[0] == '' and len(ext_filter) == 0 and len(tags) == 0:
- return []
- sql_with = None
- sql_relations_table = 'relations'
- sql_relation_data = []
- tags_data = []
- sql = ""
- if ext_filter==None:
- ext_filter = []
- sql_with_data, sql_with, sql_relation_data, sql_relations_table_tmp = extFilterGetSQL(ext_filter)
- if not sql_relations_table_tmp == None:
- sql_relations_table = sql_relations_table_tmp
- if not sql_relations_table_tmp:
- return []
- relations_count = int(cursor.execute("SELECT COUNT(*) FROM RELATION_TYPES").fetchone()[0])
- all_relation_types = '1=1'
- if 'relationtypes' in ext_filter and len(ext_filter['relationtypes']) != relations_count:
- all_relation_types = '0=1'
- if len(search_string) == 1 and search_string[0] == '':
- sql_entities = sql_with + " SELECT tblExtFilter.id AS id" \
- " FROM tblExtFilter JOIN ENTITIES ON tblExtFilter.id = ENTITIES.id" \
- " WHERE COALESCE(ENTITIES.origin_id, 0) != -1 AND parent_id IS NULL" \
- " AND (" + all_relation_types + " OR EXISTS(SELECT * FROM " + sql_relations_table_tmp + "" \
- " WHERE tblExtFilter.id=receiver_id OR tblExtFilter.id=sender_id)) AND ROWNUM <= 1001"
- rows = rows_to_dict_list(cursor.execute(build_query(sql_entities), sql_with_data+sql_relation_data))
- if ext_filter:
- rows = extFilterByRules(ext_filter, rows, cursor)
- if len(rows) > 0:
- result = []
- for row in rows:
- result.append({'id': row['id'], 'order_num': 1})
- return result
- else:
- return []
- add_where = ' 1=1 '
- if sql_with == None:
- add_where = ' ROWNUM <= 1001 '
- where_cont, where_name, order_sql, string_data = gen_sql_var(gen_all_ngrams(search_string))
- if tags is not None and tags != [] and string_data[0] == '':
- s = ','
- tags_tpl = ["%s"] * len(tags)
- tags_tpl = s.join(tags_tpl)
- tags_data = [int(tag) for tag in tags]
- sql = " SELECT DISTINCT entities.id as id, entities.name as name, entity_types.name as type, 0 as order_num" \
- " FROM entities JOIN entity_types ON entities.type_id = entity_types.id " \
- " LEFT JOIN entities_tags ON entities.id = entities_tags.entity_id " \
- " LEFT JOIN tags ON entities_tags.tag_id = tags.id " \
- " WHERE COALESCE(entities.origin_id, 0) != -1 AND parent_id IS NULL AND "+add_where+" AND ((tags.id) IN (" + tags_tpl + ")) ORDER BY entities.id "
- else:
- sql_body_facts = 'SELECT entity_id id, {} num ' \
- 'FROM entity_facts ' \
- 'WHERE ({}) '
- sql_body_entities = 'SELECT id, {} num ' \
- 'FROM entities ' \
- 'WHERE ({}) AND COALESCE(origin_id, 0) != -1 AND parent_id IS NULL '
- if len(where_cont) != 0:
- sql = "WITH t0 AS (" + sql_body_facts.format(order_sql[0], where_cont[0]) + ")"
- for i, where in enumerate(where_cont[1:]):
- sql = sql + ", t" + str(i + 1) + " AS (" + sql_body_facts.format(order_sql[i + 1], where) + ")"
- for i, where in enumerate(where_name):
- sql = sql + ", t" + str(len(where_cont) + i) + " AS (" + sql_body_entities.format(
- str(10 ** len(where_cont)) + '*' + order_sql[i], where) + ")"
- sql = sql + "SELECT * FROM (SELECT id, sum(num) order_num " \
- "FROM (" + ' union all '.join(
- ["SELECT id, num FROM t" + str(i) for i in range(len(where_cont) + len(where_name))])
- sql = sql + " ORDER BY num DESC) GROUP BY id ORDER BY order_num DESC) " \
- " WHERE " + add_where + " ORDER BY order_num DESC"
- if string_data[0]!='':
- string_data = tags_data + string_data + string_data
- else:
- string_data = tags_data
- if not sql_with==None:
- sql = sql_with+" SELECT TT.id,TT.order_num FROM ("+sql+") TT JOIN tblExtFilter ON tblExtFilter.id=TT.id WHERE ROWNUM<=1001"
- string_data = sql_with_data+string_data
- sql = "SELECT * FROM (" + sql + ") WHERE " + all_relation_types + " OR EXISTS(SELECT * FROM (" + sql_relations_table_tmp + ") " \
- " WHERE id=receiver_id OR id=sender_id)"
- cursor.execute(
- "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'"
- " NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD'")
- cursor.execute(build_query(sql), string_data + sql_relation_data)
- rows = rows + rows_to_dict_list(cursor)
- if ext_filter:
- rows = extFilterByRules(ext_filter, rows, cursor)
- if len(rows) > 0:
- result = []
- for row in rows:
- result.append({'id': row['id'], 'order_num': row['order_num']})
- return result
- else:
- return []
Add Comment
Please, Sign In to add comment