Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a correct way to remove node/relationship properties? #93

Closed
Ansis100 opened this issue Jan 23, 2024 · 5 comments · Fixed by #97
Closed

Is there a correct way to remove node/relationship properties? #93

Ansis100 opened this issue Jan 23, 2024 · 5 comments · Fixed by #97

Comments

@Ansis100
Copy link
Contributor

Neo4j does not support null as a property value. This also means that the union type Neo4jSupportedProperties does not contain null. However, the model validator accepts null and model TypeScript definitions can be set to property?: null | type.

This mostly works and successfully removes the property, excluding some weird edge cases. For example, if the revalidator schema is set to 'type' instead of ['null', 'type'], then updating the object using the model static will work fine, however, updating using instance.property = value and instance.save() will cause a validation error.

If this is the intended usage, it would be nice to specify this in the docs and maybe add null to Neo4jSupportedProperties to avoid some TypeScript weirdness when using Neogma TS generics. If not, then it might be useful to add some kind of specific property removing mechanism to modifying methods.

@Ansis100
Copy link
Contributor Author

Ansis100 commented Jan 23, 2024

#80 seems to be relevant here. Adding support for null values would "fix" this workaround, and leave us with no way of removing properties. I guess it depends on whether or not you consider null and undefined the same thing in the Neo4j context.

@Ansis100
Copy link
Contributor Author

@themetalfleece do you have some sort of plan for implementing this? If you could provide some sort of spec on how you imagine this might be implemented, I would gladly create a PR.

I imagine something like another property on the second update model static parameter params:

    update: (data: Partial<Properties>, params?: GenericConfiguration & {
        where?: WhereParamsI;
        /** defaults to false. Whether to return the properties of the nodes after the update. If it's false, the first entry of the return value of this function will be an empty array */
        return?: boolean;
        removeProperties?: string[]; // This is new!
    }) => Promise<[Instance[], QueryResult]>;

Even better if there's some type checking where the removeProperties array only accepts model property keys as values.

This, however, does not provide a way to remove properties from an instance. That could be fixed by creating a new instance method removeProperties(propertyKeys: string[]) which somehow lets save() know that these properties should be removed.

We could just lean on the fact that null values already remove the properties and fix any Typescript or validation issues that arise from that, but I have a feeling that an explicit removeProperties is less ambiguous.

@themetalfleece
Copy link
Owner

Hey, thanks for offering to create a PR for this!

I was thinking that we could add an operator, which would be used like this:

user.update({
  name: 'Bob',
  age: { [Op.remove]: true }
});

What do you think of this? :)

I'm also ok with adding proper support for null and have it remove the properties.

@Ansis100
Copy link
Contributor Author

I wouldn't have guessed that we can use the operators like that, but that looks even better than my proposal!
I'll get on that and try to figure it out.

@themetalfleece
Copy link
Owner

themetalfleece commented Mar 26, 2024

Cheers! Right now the operators are used for "Where" only (for finding), but we can definitely use them (or a new set of operators) for setting/updating values.
So, it makes sense to rename the existing Op object to WhereOp (or, create a new one for backwards compability), and add a new one called SetOp/UpdateOp or something similar, which will have the remove operator? 🤔 That way, the two types of operators won't be mixed together.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants