Closed ryanjdew closed 8 years ago
Hey, sorry for the delayed response. What would be the breadth of this feature? Is it just an additional JS API, or would it handle constraints in string-queries? Facets that match the prefix?
I was thinking it could be used with custom constraints like the one I added for date ranges here: https://github.com/marklogic/slush-marklogic-node/pull/266/files. I was thinking that you could register a prefix like 'dateTimeStart' and 'dateTimeEnd' then mlsearch could handle writing to and generating an additional query based on the function registered from the URL.
So, totally separate from the existing query-building approach for string queries, constraint queries, etc.?
I was thinking it would only affect two places.
In the function generating the query it can obviously choose to use MLQueryBuilder, etc. Perhaps mlSearch already has something that I'm missing that I could be leveraged to accomplish that? Basically the problem I'm trying to solve is adding custom additional queries and still allow it to be deep linked with minimal effort from the person using ml-search.
There is some support in MLSearchController
for handling additional URL params. Here's a basic example that conditionally adds a zip
URL param and an associated radius query (you'd add the following to your search controller, based on https://github.com/joemfb/ml-search-ng/blob/master/sample/search-ctrl.js):
var qb = mlSearch.qb;
ctrl.zip = null;
// implement superCtrl extension method
ctrl.parseExtraURLParams = function () {
var zip = $location.search().zip
if (ctrl.zip !== zip) {
ctrl.zip = zip;
return true
}
return false
};
// implement superCtrl extension method
ctrl.updateExtraURLParams = function () {
if (ctrl.zip) {
$location.search('zip', ctrl.zip);
} else {
$location.search( 'zip', null );
}
};
ctrl._search = function () {
mlSearch.clearAdditionalQueries();
addRadiusQuery();
superCtrl._search.call(ctrl);
};
function addRadiusQuery () {
if (ctrl.zip) {
mlSearch.addAdditionalQuery({
'custom-constraint-query': {
'constraint-name': 'nearzip',
// radius around zip code, in miles
'radius': 10,
'zip': ctrl.zip
}});
}
}
This works by extending the controller search implementation function (ctrl._search
), and utilizing the extension methods ctrl.parseExtraURLParams
and ctrl.updateExtraURLParams
. The super ctrl takes care of calling those at the right time. (documented here: https://joemfb.github.io/ml-search-ng/MLSearchController.html; note that ctrl.parseExtraURLParams
returns a boolean specifying whether or not a search should be run)
To me, the ugliest part about this is having to first clear all the additional queries, then conditionally add the custom-constraint-query
; I'd prefer to have a method on mlSearch
that just accepted a function that would conditionally return a query.
This is a totally generic extension pattern, so it's not exactly what you're looking for. However, it does show the edge cases you have to handle, and gives you a ctrl instance variable (ctrl.zip
) that the UI can interact with.
I'm a little hesitant to add APIs for this feature without considering how it could more closely integrate with the rest of the query-building code. I'd personally like to have a flexible, unified system for managing different types of constraints rather than the basic facet constraints / string-query approach that we currently have, but I haven't had the time to propose a design for such a system ...
What are your thoughts on this example?
I actually really like that example. I think it makes it simple enough and I'm fine with this ticket being closed.
Great, I'm glad that's helpful. I need to incorporate examples into the documentation; the API surface is already too big. I'm not really sure how to do that on top of the existing JSDoc-based approach.
Let me know if you have or see any good documentation like that.
Nice example indeed. Might be nice though if it were slightly easier to manage the additional queries, somehow categorize them. Would something like mlSearch.addExtraQueries('zip', radiusQuery)
, and mlSearch.removeExtraQueries('zip')
make sense?
I was thinking it would be nice to be able to register a handler for custom constraints. I envision the use being something like this:
I can work on it, but would love feedback on API or any other concerns that there may be.