react-querybuilder/react-querybuilder

parseMongoDB: optional parameter to keep query as it is if a $not operator specifies a single, boolean condition

christinalettner1 opened this issue · 7 comments

Hi!

According to the Doc for Migrating to v7, this behaviour was added:
"parseMongoDB now generates more concise queries when it encounters $not operators that specify a single, boolean condition. Whereas previously that would yield a group with not: true, now it generates a rule with a negated operator ("=" becomes "!=", "contains" becomes "doesNotContain", etc.)."

Can you add an optional parameter that prevents that behaviour? In my case, my QueryBuilder does not know the negations of contains etc which leads to a broken UI when the query is automatically transformed to that.

Additionally, I have noticed that the new behaviour is kind of faulty in combination with the additionalOperators option that has been added in this issue: #612 . I added this additionalOperator to make sure that "doesNotContain" is not transformed into a regex but stays "doesNotContain":

const additionalOperators = { $doesNotContain: (field: string, operator: string, value: unknown): RuleType => { return { field, operator: 'doesNotContain', value }; } };

but this is never being called on a $not operator in combination with a $contains. Maybe in that case the additionalOperators are ignored or something like that?

Ooh, good catch. Thanks!

Would it be ok to revert to the previous behavior for additionalOperators only? I feel like the default operators can all be converted to their corresponding "negated" operator fairly reliably. If I'm wrong about that I'll definitely consider an override option.

Unfortunately in my usecase it leads to a somewhat broken UI if any of the operators are converted automatically. Due to some specifications in my project, I often only provide the user with the non-negated operators and if the query contains a negated operator, the operator selector would be displayed as empty because it doesn't know the negated operator provided.

Also, I check if the query that I have saved in my DB can be read correctly by my Querybuilder and if not, I lock the Component so that nothing is overwritten. (Some Users have some special configurations that are added directly in the DB and the UI doesn't know these configurations). This is the code for that:

const query = savedQuery ? this.parseMongoDBToQuery(savedQuery) : undefined;
const mongoQuery = query ? this.formatQueryToMongoDB(query) : '';
const locked = savedQuery != mongoQuery;

I do that by taking the saved query from the DB and call parseMongoDB with it and then taking that output and call formatQuery with it. If the saved query is not the same as the result of the formatQuery it means that the user has some special configuration and shouldn't be able to edit it through the Querybuilder to make sure nothing is overwritten.

If the formatQuery automatically transforms those $not operators, the savedQuery will always differ from the result of formatQuery and therefore my Querybuilder will be locked even though the configuration would normally be readable by it.

Ok that's definitely a valid use case. I'll add an option to prevent operator negation.

@christinalettner1 I added the preventOperatorNegation option in PR #653.

Can you test it in this sandbox? If it meets your requirement, let me know and I'll merge it and get another v7 alpha out shortly afterward.

Yes, that's perfect. Thanks for your quick solution! :)

Hello! I was wondering when you'll release another alpha with this parameter? The latest I could find was the alpha.7 and this one doesn't seem to contain the changes yet.

Hello! I was wondering when you'll release another alpha with this parameter? The latest I could find was the alpha.7 and this one doesn't seem to contain the changes yet.

We've moved v7 out of alpha. The latest v7 prerelease version is a release candidate: 7.0.0-rc.1.