Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

I'd love to see an integrated 'hash' for the current query.
This might be beyond the scope of the query builder, so I'm not sure it fits within the package, but I've found it very useful, at least when integrating the builder with tanstack query and other tools.

The way I approach this is I take the state of the builder, stringify the JSON deterministically and use xxhash (reliable and very fast, especially considering it's characteristics) on that.
The benefit here is that, if you are relying on tanstack query to for example, send the query to parse to the backend or provide results, you can utilize this hash as part of the query key to actually trigger that update / fetch.

In my use case (and probably for most situations) I've debounced the hashing function. The hashing and everything is extremely efficient, but it's relatively pointless to spam a user's typing, when you're dealing with a query builder that offers complex filtering and is likely not targeting your more efficient autocomplete endpoints / indexes.

https://github.com/Cyan4973/xxHash
https://github.com/Daninet/hash-wasm (there might be better WASM ones? I don't really know how much it matters here)

You must be logged in to vote

Replies: 2 comments · 2 replies

Comment options

We use a hash in the website demo, actually, but it's just gzip+base64 and not deterministic to my knowledge. Code is here. Its only real purpose is to reduce the size of the style library links and the permalink. I think I tried to debounce it at some point a while back, but gave up after running into issues trying to get it to work within the Docusaurus paradigm.

A fast, deterministic hash method certainly sounds useful in this space. My first inclination is to agree that it might be out of scope for RQB, but I'd be willing to entertain suggestions.

If we didn't have to add a dependency (although I would consider vendoring something, maybe that JS port of xxhash?), what sort of API would you expect from this library? Would it integrate with the QueryBuilder component itself somehow, or just be an additional tool provided for convenience?

You must be logged in to vote
0 replies
Comment options

Having thought about it more, I'm leaning towards utility. You can basically call getHash(thisIsMyQueryBuilderState) from anywhere you have access to the RQB state, no problem, and generally someone's usage of a function like that, would be pretty decoupled from the QueryBuilder itself.
Really the reason you'd integrate it with RQB would be if you decided to use it internally in the component's logic somehow. If you do have some need for this, I'd say my choice of XXHash was pretty reflexive since I use it alot. Really the cleanest option would be no deps, go as simple as possible, take the idGenerator route so a user can swap in whatever they use. The part that would trip someone up anyways is stringifying objects deterministically (while retaining array of objects input ordering since in a query builder, that order very much matters).

You must be logged in to vote
2 replies
@jakeboone02
Comment options

What do think about this?

formatQuery(query, 'hash')

Another question: Should we do any query manipulation before hashing? I'm thinking of the "json_without_ids" format, which I usually recommend for serialization. It strips out id and path properties which are almost always unnecessary/irrelevant for persistent storage, and I think the same would be true for a hash function. I can't think of a reason why two queries that were equivalent except for their id properties wouldn't be executed or evaluated the same way.

@Play-AV
Comment options

What do think about this?

formatQuery(query, 'hash')

Another question: Should we do any query manipulation before hashing? I'm thinking of the "json_without_ids" format, which I usually recommend for serialization. It strips out id and path properties which are almost always unnecessary/irrelevant for persistent storage, and I think the same would be true for a hash function. I can't think of a reason why two queries that were equivalent except for their id properties wouldn't be executed or evaluated the same way.

Sounds reasonable to me.

Personally, I didn't really consider stripping those out, but I can see that making sense. Somewhat related to my long ramble in the other discussion, I mentioned that this internal model I had been working on, looked very similar to how it was handled in RQB. I had implemented that, initially for a feature to utilize user defined filter queries to act as a source for more selective entity notifications / subscriptions.

In that model, the ids of each 'rule' were relatively important for other functions and how said filters were saved into the database for that service. As an example those ids were used to flag 'broken' rules. Consider the situation where a field was available months ago as the notification filter was created, but no longer is, it was helpful to highlight what the actual issue was as a worker was processing it (the 'queries' run against the data systems on a loose interval).

The only real hiccup I can see going the json_without_ids route is if someone was trying to match the hashing from the frontend to their backend (maybe they need to temporarily cache a larger result set or maintain a cursor or something), and their backend is being handed the query with the ids and or paths. Ultimately, it would be trivial to strip those yourself, so really, as long as the docs for it explain that it's leveraging json_without_ids, I can see that working pretty well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
💡
Ideas
Labels
None yet
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.