search is completely working in frontend now
This commit is contained in:
parent
b0d6f724ef
commit
1cba014948
@ -2,33 +2,57 @@ import logging
|
||||
import json
|
||||
from elasticsearch import Elasticsearch
|
||||
from elasticsearch_dsl import Search, Q
|
||||
from elasticsearch_dsl.connections import connections
|
||||
|
||||
from pillar import current_app
|
||||
|
||||
#elk_hosts = current_app.config['ELASTIC_SEARCH_HOSTS']
|
||||
#
|
||||
#connections.create_connection(
|
||||
# hosts=elk_hosts,
|
||||
# sniff_on_start=True,
|
||||
# timeout=20)
|
||||
#
|
||||
client = Elasticsearch()
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
node_agg_terms = ['node_type', 'media', 'tags', 'is_free']
|
||||
user_agg_terms = ['roles', ]
|
||||
|
||||
|
||||
def add_aggs_to_search(search):
|
||||
def add_aggs_to_search(search, agg_terms):
|
||||
"""
|
||||
Add facets / aggregations to the search result
|
||||
"""
|
||||
|
||||
agg_terms = ['node_type', 'media', 'tags', 'is_free']
|
||||
|
||||
for term in agg_terms:
|
||||
search.aggs.bucket(term, 'terms', field=term)
|
||||
|
||||
#search.aggs.bucket('project', 'terms', field='project.name')
|
||||
|
||||
def make_must(terms):
|
||||
"""
|
||||
Given some term parameters
|
||||
we must match those
|
||||
"""
|
||||
|
||||
must = []
|
||||
|
||||
for field, value in terms.items():
|
||||
|
||||
print(field, value)
|
||||
|
||||
if value:
|
||||
must.append({'match': {field: value}})
|
||||
|
||||
return must
|
||||
|
||||
|
||||
def nested_bool(should, terms):
|
||||
"""
|
||||
"""
|
||||
must = []
|
||||
must = make_must(terms)
|
||||
bool_query = Q('bool', should=should)
|
||||
must.append(bool_query)
|
||||
bool_query = Q('bool', must=must)
|
||||
|
||||
search = Search(using=client)
|
||||
search.query = bool_query
|
||||
|
||||
return search
|
||||
|
||||
|
||||
def do_search(query: str, terms: dict) -> dict:
|
||||
@ -46,16 +70,14 @@ def do_search(query: str, terms: dict) -> dict:
|
||||
Q('term', tags=query),
|
||||
]
|
||||
|
||||
#must = []
|
||||
|
||||
#for field, value in terms.items():
|
||||
# must.append(
|
||||
|
||||
bool_query = Q('bool', should=should)
|
||||
if query:
|
||||
search = nested_bool(should, terms)
|
||||
else:
|
||||
# do a match all for the aggregations
|
||||
search = Search(using=client)
|
||||
search.query = bool_query
|
||||
search.query = Q('term', _type='node')
|
||||
|
||||
add_aggs_to_search(search)
|
||||
add_aggs_to_search(search, node_agg_terms)
|
||||
|
||||
if current_app.config['DEBUG']:
|
||||
print(json.dumps(search.to_dict(), indent=4))
|
||||
@ -68,7 +90,7 @@ def do_search(query: str, terms: dict) -> dict:
|
||||
return response.to_dict()
|
||||
|
||||
|
||||
def do_user_search(query: str) -> dict:
|
||||
def do_user_search(query: str, terms: dict) -> dict:
|
||||
"""
|
||||
return user objects
|
||||
"""
|
||||
@ -76,17 +98,23 @@ def do_user_search(query: str) -> dict:
|
||||
Q('match', username=query),
|
||||
Q('match', full_name=query),
|
||||
]
|
||||
bool_query = Q('bool', should=should)
|
||||
|
||||
if query:
|
||||
search = nested_bool(should, terms)
|
||||
else:
|
||||
# do a match all for the aggregations
|
||||
search = Search(using=client)
|
||||
search.query = bool_query
|
||||
search.query = Q('term', _type='user')
|
||||
|
||||
add_aggs_to_search(search, user_agg_terms)
|
||||
|
||||
if current_app.config['DEBUG']:
|
||||
log.debug(json.dumps(search.to_dict(), indent=4))
|
||||
print(json.dumps(search.to_dict(), indent=4))
|
||||
|
||||
response = search.execute()
|
||||
|
||||
if current_app.config['DEBUG']:
|
||||
log.debug('%s', json.dumps(response.to_dict(), indent=4))
|
||||
print(json.dumps(response.to_dict(), indent=4))
|
||||
|
||||
return response.to_dict()
|
||||
|
||||
|
@ -1,22 +1,15 @@
|
||||
import json
|
||||
import logging
|
||||
|
||||
from bson import ObjectId
|
||||
from flask import Blueprint, request, current_app, make_response, url_for
|
||||
from flask import Response
|
||||
from flask import Blueprint, request
|
||||
from werkzeug import exceptions as wz_exceptions
|
||||
from pillar.api.utils import authorization, jsonify
|
||||
|
||||
from pillar.api.utils import authorization, jsonify, str2id
|
||||
from pillar.api.utils import mongo
|
||||
from pillar.api.utils.authorization import require_login, check_permissions
|
||||
from pillar.auth import current_user
|
||||
|
||||
from . import queries
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
blueprint_search = Blueprint('elksearch', __name__)
|
||||
|
||||
from . import queries
|
||||
|
||||
|
||||
def _valid_search() -> str:
|
||||
@ -25,19 +18,23 @@ def _valid_search() -> str:
|
||||
"""
|
||||
|
||||
searchword = request.args.get('q', '')
|
||||
if not searchword:
|
||||
raise wz_exceptions.BadRequest('You are forgetting a "?q=whatareyoulookingfor"')
|
||||
# if not searchword:
|
||||
# raise wz_exceptions.BadRequest(
|
||||
# 'You are forgetting a "?q=whatareyoulookingfor"')
|
||||
return searchword
|
||||
|
||||
|
||||
def _term_filters() -> dict:
|
||||
"""
|
||||
Check if frontent want to filter stuff
|
||||
Check if frontent wants to filter stuff
|
||||
on specific fields AKA facets
|
||||
"""
|
||||
|
||||
terms = [
|
||||
'node_type', 'media',
|
||||
'tags', 'is_free', 'projectname']
|
||||
'tags', 'is_free', 'projectname',
|
||||
'roles',
|
||||
]
|
||||
|
||||
parsed_terms = {}
|
||||
|
||||
@ -60,7 +57,8 @@ def search_user():
|
||||
|
||||
searchword = _valid_search()
|
||||
|
||||
data = queries.do_user_search(searchword)
|
||||
terms = _term_filters()
|
||||
data = queries.do_user_search(searchword, terms)
|
||||
|
||||
return jsonify(data)
|
||||
|
||||
|
@ -8,7 +8,9 @@ $(document).ready(function() {
|
||||
var $hits = $('#hits');
|
||||
var $stats = $('#stats');
|
||||
var $facets = $('#facets');
|
||||
//var facets = [];
|
||||
var $pagination = $('#pagination');
|
||||
var what = '';
|
||||
|
||||
// Templates binding
|
||||
var hitTemplate = Hogan.compile($('#hit-template').text());
|
||||
@ -19,6 +21,7 @@ $(document).ready(function() {
|
||||
|
||||
// something elasticy!
|
||||
var search = elasticSearcher;
|
||||
|
||||
// facets: $.map(FACET_CONFIG, function(facet) {
|
||||
// return !facet.disjunctive ? facet.name : null;
|
||||
// }),
|
||||
@ -137,17 +140,23 @@ $(document).ready(function() {
|
||||
// If no results
|
||||
if (content.hits.length === 0) {
|
||||
$facets.empty();
|
||||
facets =[];
|
||||
return;
|
||||
}
|
||||
|
||||
var storeValue = function (values, label){
|
||||
|
||||
|
||||
return function(item){
|
||||
|
||||
let refined = search.isRefined(label, item.key);
|
||||
|
||||
values.push({
|
||||
facet: label,
|
||||
label: item.key,
|
||||
value: item.key,
|
||||
count: item.doc_count,
|
||||
refined: refined,
|
||||
});
|
||||
};
|
||||
};
|
||||
@ -164,6 +173,8 @@ $(document).ready(function() {
|
||||
|
||||
if (buckets.length === 0) { continue; }
|
||||
|
||||
|
||||
|
||||
buckets.forEach(storeValue(values, label));
|
||||
|
||||
facets.push({
|
||||
@ -252,7 +263,7 @@ $(document).ready(function() {
|
||||
});
|
||||
|
||||
$(document).on('click', '.toggleRefine', function() {
|
||||
search.addTerm($(this).data('facet'), $(this).data('value'));
|
||||
search.toggleTerm($(this).data('facet'), $(this).data('value'));
|
||||
search.execute();
|
||||
return false;
|
||||
});
|
||||
@ -277,6 +288,7 @@ $(document).ready(function() {
|
||||
$('#facets').on("mouseenter mouseleave", ".button-checkbox", function(e) {
|
||||
$(this).parent().find('.facet_link').toggleClass("hover");
|
||||
});
|
||||
|
||||
$('#facets').on("mouseenter mouseleave", ".facet_link", function(e) {
|
||||
$(this).parent().find('.button-checkbox button.btn').toggleClass("hover");
|
||||
});
|
||||
@ -330,7 +342,7 @@ $(document).ready(function() {
|
||||
}
|
||||
var query = decodeURIComponent(sURLVariables[0].split('=')[1]);
|
||||
$inputField.val(query);
|
||||
search.setQuery(query);
|
||||
search.setQuery(query, what);
|
||||
|
||||
for (var i = 2; i < sURLVariables.length; i++) {
|
||||
var sParameterName = sURLVariables[i].split('=');
|
||||
@ -362,4 +374,8 @@ $(document).ready(function() {
|
||||
location.replace(urlParams);
|
||||
}
|
||||
|
||||
// do empty search to fill aggregations
|
||||
search.setQuery('', what);
|
||||
search.execute();
|
||||
|
||||
});
|
||||
|
@ -14,7 +14,7 @@ var elasticSearcher = (function() {
|
||||
page: 0,
|
||||
|
||||
setQuery: (function(q, _url){
|
||||
console.log('setQuery!: ' + q);
|
||||
console.log('setQuery!: ' + q + 'what :'+ _url);
|
||||
deze.query=q;
|
||||
if (_url !== undefined) {
|
||||
deze.url=_url;
|
||||
@ -45,8 +45,19 @@ var elasticSearcher = (function() {
|
||||
return deze.newhits.aggregations;
|
||||
}),
|
||||
|
||||
addTerm: (function(term, value){
|
||||
toggleTerm: (function(term, value){
|
||||
if (deze.terms[term] !== undefined) {
|
||||
delete deze.terms[term];
|
||||
} else {
|
||||
deze.terms[term] = value;
|
||||
}
|
||||
}),
|
||||
|
||||
isRefined: (function(term, value){
|
||||
if (deze.terms[term] === value) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}),
|
||||
|
||||
//get response from elastic and rebuild json
|
||||
@ -89,7 +100,8 @@ var elasticSearcher = (function() {
|
||||
setCurrentPage: deze.setCurrentPage,
|
||||
query: deze.query,
|
||||
page: deze.page,
|
||||
addTerm: deze.addTerm,
|
||||
toggleTerm: deze.toggleTerm,
|
||||
isRefined: deze.isRefined,
|
||||
};
|
||||
|
||||
})();
|
||||
|
@ -22,6 +22,7 @@ style.
|
||||
type="text",
|
||||
name="q",
|
||||
id="q",
|
||||
what="/user",
|
||||
autocomplete="off",
|
||||
spellcheck="false",
|
||||
autocorrect="false",
|
||||
@ -92,14 +93,6 @@ script(type="text/template", id="stats-template")
|
||||
| {% endblock %}
|
||||
|
||||
| {% block footer_scripts %}
|
||||
script().
|
||||
var APPLICATION_ID = '{{config.ALGOLIA_USER}}';
|
||||
var SEARCH_ONLY_API_KEY = '{{config.ALGOLIA_PUBLIC_KEY}}';
|
||||
var INDEX_NAME = '{{config.ALGOLIA_INDEX_USERS}}';
|
||||
var sortByCountDesc = null;
|
||||
var FACET_CONFIG = [
|
||||
{ name: 'roles', title: 'Roles', disjunctive: false, sortFunction: sortByCountDesc },
|
||||
];
|
||||
|
||||
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/algoliasearch-3.19.0.min.js')}}")
|
||||
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/algoliasearch.helper.min.js') }}")
|
||||
|
Loading…
x
Reference in New Issue
Block a user