Skip to content

Commit

Permalink
add advanced search filter, re #4771
Browse files Browse the repository at this point in the history
  • Loading branch information
apeters committed May 7, 2019
1 parent 8b96d6a commit 0151ddb
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 112 deletions.
222 changes: 112 additions & 110 deletions arches/app/media/js/views/components/search/advanced-search.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,121 +7,123 @@ define([
'datatype-config-components',
'bindings/let'
], function(_, ko, koMapping, BaseFilter, arches) {
return ko.components.register('advanced-search', {
var componentName = 'advanced-search';
return ko.components.register(componentName, {
viewModel: BaseFilter.extend({
initialize: function(options) {
var self = this;
this.searchableGraphs = [];
this.cards = options.cards;
this.datatypelookup = {};
this.facetFilterText = ko.observable('');
_.each(options.datatypes, function(datatype) {
self.datatypelookup[datatype.datatype] = datatype;
});
_.each(options.cards, function(card) {
card.nodes = _.filter(options.nodes, function(node) {
return node.nodegroup_id === card.nodegroup_id;
});
card.addFacet = function() {
self.newFacet(card);
};
});
_.each(options.graphs, function(graph) {
if (graph.isresource && graph.isactive) {
var graphCards = _.filter(options.cards, function(card) {
return card.graph_id === graph.graphid && card.nodes.length > 0;
});
if (graphCards.length > 0) {
_.each(graphCards, function(card) {
card.getGraph = function() {
return graph;
};
});
graph.cards = ko.computed(function() {
var facetFilterText = self.facetFilterText().toLowerCase();
if (facetFilterText) {
return _.filter(graphCards, function(card) {
return card.name.toLowerCase().indexOf(facetFilterText) > -1;
});
} else {
return graphCards;
}
});
self.searchableGraphs.push(graph);
}
}
});
this.filter = {
facets: ko.observableArray()
};
initialize: function(options) {
var self = this;
BaseFilter.prototype.initialize.call(this, options);
this.searchableGraphs = [];
this.cards = options.cards;
this.datatypelookup = {};
this.facetFilterText = ko.observable('');
_.each(options.datatypes, function(datatype) {
this.datatypelookup[datatype.datatype] = datatype;
}, this);
_.each(options.cards, function(card) {
card.nodes = _.filter(options.nodes, function(node) {
return node.nodegroup_id === card.nodegroup_id;
});
card.addFacet = function() {
self.newFacet(card);
};
}, this);
_.each(options.graphs, function(graph) {
if (graph.isresource && graph.isactive) {
var graphCards = _.filter(options.cards, function(card) {
return card.graph_id === graph.graphid && card.nodes.length > 0;
});
if (graphCards.length > 0) {
_.each(graphCards, function(card) {
card.getGraph = function() {
return graph;
};
});
graph.cards = ko.computed(function() {
var facetFilterText = this.facetFilterText().toLowerCase();
if (facetFilterText) {
return _.filter(graphCards, function(card) {
return card.name.toLowerCase().indexOf(facetFilterText) > -1;
});
} else {
return graphCards;
}
}, this);
this.searchableGraphs.push(graph);
}
}
}, this);
this.filter = {
facets: ko.observableArray()
};

BaseFilter.prototype.initialize.call(this, options);
},
this.filters[componentName](this);
this.restoreState();
},

newFacet: function(card) {
var facet = {
card: card,
value: {
op: ko.observable('and')
}
};
_.each(facet.card.nodes, function(node) {
facet.value[node.nodeid] = ko.observable({});
});
this.filter.facets.push(facet);
},
updateQuery: function() {
var queryObj = this.query();
var filtersApplied = this.filter.facets().length > 0;
if (filtersApplied) {
var facets = this.filter.facets();
var advanced = [];
_.each(facets, function(facet) {
var value = koMapping.toJS(facet.value);
advanced.push(value);
});
queryObj[componentName] = JSON.stringify(advanced);
} else {
delete queryObj[componentName];
}
this.query(queryObj);
},

appendFilters: function(filterParams) {
var filtersApplied = this.filter.facets().length > 0;
if (filtersApplied) {
var facets = this.filter.facets();
var advanced = [];
_.each(facets, function(facet) {
var value = koMapping.toJS(facet.value);
newFacet: function(card) {
var facet = {
card: card,
value: {
op: ko.observable('and')
}
};
_.each(facet.card.nodes, function(node) {
facet.value[node.nodeid] = ko.observable({});
});
this.filter.facets.push(facet);
},

advanced.push(value);
});
filterParams.advanced = JSON.stringify(advanced);
}
return filtersApplied;
},
restoreState: function() {
var query = this.query();
if (componentName in query) {
var facets = JSON.parse(query[componentName]);
_.each(facets, function(facet) {
var nodeIds = _.filter(Object.keys(facet), function(key) {
return key !== 'op';
});
var card = _.find(this.cards, function(card) {
var cardNodeIds = _.map(card.nodes, function(node) {
return node.nodeid;
});
return _.contains(cardNodeIds, nodeIds[0]);
}, this);
if (card) {
_.each(card.nodes, function(node) {
facet[node.nodeid] = ko.observable(facet[node.nodeid]);
});
facet.op = ko.observable(facet.op);
this.filter.facets.push({
card: card,
value: facet
});
}
}, this);
}
},

restoreState: function(query) {
var self = this;
var doQuery = false;
if ('advanced' in query) {
var facets = JSON.parse(query.advanced);
_.each(facets, function(facet) {
var nodeIds = _.filter(Object.keys(facet), function(key) {
return key !== 'op';
});
var card = _.find(self.cards, function(card) {
var cardNodeIds = _.map(card.nodes, function(node) {
return node.nodeid;
});
return _.contains(cardNodeIds, nodeIds[0]);
});
if (card) {
_.each(card.nodes, function(node) {
facet[node.nodeid] = ko.observable(facet[node.nodeid]);
});
facet.op = ko.observable(facet.op);
self.filter.facets.push({
card: card,
value: facet
});
doQuery = true;
}
});
}
return doQuery;
},

clear: function() {
this.filter.facets([]);
return;
}
}),
clear: function() {
this.filter.facets([]);
return;
}
}),
template: { require: 'text!templates/views/components/search/advanced-search.htm' }
});
});
});
46 changes: 44 additions & 2 deletions arches/app/search/components/advanced_search.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
from arches.app.models import models
from arches.app.models.system_settings import settings
from arches.app.datatypes.datatypes import DataTypeFactory
from arches.app.utils.betterJSONSerializer import JSONDeserializer
from arches.app.search.elasticsearch_dsl_builder import Bool, Nested
from arches.app.search.components.base import BaseSearchFilter

details = {
"searchcomponentid": "",
"name": "Advanced",
Expand All @@ -13,7 +20,42 @@
}


class AdvancedSearch():
class AdvancedSearch(BaseSearchFilter):

def append_dsl(self, querysting_params, query_dsl, permitted_nodegroups, include_provisional):
pass
advanced_filters = JSONDeserializer().deserialize(querysting_params)
datatype_factory = DataTypeFactory()
search_query = Bool()
advanced_query = Bool()
grouped_query = Bool()
grouped_queries = [grouped_query]
for index, advanced_filter in enumerate(advanced_filters):
tile_query = Bool()
for key, val in advanced_filter.iteritems():
if key != 'op':
node = models.Node.objects.get(pk=key)
if request.user.has_perm('read_nodegroup', node.nodegroup):
datatype = datatype_factory.get_instance(node.datatype)
datatype.append_search_filters(val, node, tile_query, request)
nested_query = Nested(path='tiles', query=tile_query)
if advanced_filter['op'] == 'or' and index != 0:
grouped_query = Bool()
grouped_queries.append(grouped_query)
grouped_query.must(nested_query)
for grouped_query in grouped_queries:
advanced_query.should(grouped_query)
search_query.must(advanced_query)

def view_data(self):
ret = {}
resource_graphs = models.GraphModel.objects.exclude(pk=settings.SYSTEM_SETTINGS_RESOURCE_MODEL_ID).exclude(isresource=False).exclude(isactive=False)
searchable_datatypes = [d.pk for d in models.DDataType.objects.filter(issearchable=True)]
searchable_nodes = models.Node.objects.filter(graph__isresource=True, graph__isactive=True, datatype__in=searchable_datatypes, issearchable=True)
resource_cards = models.CardModel.objects.filter(graph__isresource=True, graph__isactive=True)

ret['graphs'] = resource_graphs
ret['datatypes'] = searchable_datatypes
ret['nodes'] = searchable_nodes
ret['cards'] = resource_cards

return ret

0 comments on commit 0151ddb

Please sign in to comment.