meteorhacks / search-source

Reactive Data Source for Search
MIT License
146 stars 33 forks source link

Searching for other value types than strings #43

Open derwaldgeist opened 8 years ago

derwaldgeist commented 8 years ago

First of all: I really like this package, it helps a lot to implement search functionality.

Today, I tried to set-up a search that uses an array of strings instead of a plain string as an input parameter. This did not work. Instead, I got the following error message:

I20151106-13:55:32.616(1)? Exception while invoking method 'search.source' Error: Match error: Failed Match.OneOf or Match.Optional validation
I20151106-13:55:32.616(1)?     at checkSubtree (packages/check/match.js:244:1)
I20151106-13:55:32.616(1)?     at check (packages/check/match.js:32:1)
I20151106-13:55:32.617(1)?     at [object Object].Meteor.methods.search.source (packages/meteorhacks:search-source/lib/server.js:12:1)
I20151106-13:55:32.617(1)?     at [object Object].methodMap.(anonymous function) (packages/meteorhacks:kadira/lib/hijack/wrap_session.js:164:1)
I20151106-13:55:32.617(1)?     at packages/check/match.js:109:1
I20151106-13:55:32.617(1)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20151106-13:55:32.617(1)?     at Object.Match._failIfArgumentsAreNotAllChecked (packages/check/match.js:108:1)
I20151106-13:55:32.617(1)?     at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1614:1)
I20151106-13:55:32.617(1)?     at packages/ddp/livedata_server.js:648:1
I20151106-13:55:32.617(1)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20151106-13:55:32.617(1)? Sanitized and reported to the client as: Match failed [400]
I20151106-13:55:32.617(1)? 

Is there any particular reason why the input parameter is limited to a string? I will now concat the array using a delimiter character as a work-around, but it would be nicer if I could send arrays or plain objects directly.

steinitz-zz commented 8 years ago

I've just made a custom version for myself that accepts an object. Besides adding "Object" to the check function arguments in the search.source Meteor call, I had to make several surgical changes to the client code to get it all to work. For instance:

  1. to continue to accept simple strings, added argument checking which falls back to the existing code
  2. allowed optionally specifying a key to use to highlight the search results (as it currently does for the simple string)
  3. added a callback to build the mongo selector on the client (my case included a date range plus a string)
  4. modified the search history key based on the search object contents
  5. other

Separate but related to those modifications was an issue of duplicate Mongo-selector-building code on the server and client. Let me see if I can explain.

The existing SearchSource code requires the user to define her own server-side Mongo selector but, oddly, I thought, it builds the client-side selector (an $or) in its own code (see getData in client.js). Having added an optional callback for the client selector (see item 3, above), I tried get SearchSource itself to share a Mongo-selector-building function between the client and server.

After some struggle and breakpointing I was enlightened to the fact that there's no simple way to pass a function between client and server via, say, the existing SearchSource ‘option’ argument. So, I decided to share a mongo-selector-building function externally from SearchSource: a shared function available to the client and server callbacks. Less modular but fine for now.

It works well. At present, I have as search criteria only a date range and a string, but there’s no limit on the complexity of search allowed by this architecture. That’s satisfying.

I hope this little note encourages you.

derwaldgeist commented 8 years ago

Thanks a lot for these insights!