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

Fix script upsert on bulk requests #1974

Merged
merged 18 commits into from
Oct 25, 2021
Merged

Fix script upsert on bulk requests #1974

merged 18 commits into from
Oct 25, 2021

Conversation

dsgrillo
Copy link
Contributor

@dsgrillo dsgrillo commented Aug 27, 2021

According to the documentation, it's required to add the scripted_upsert=true for running a upsert with script.
If the flag is not set, the document is added, but without running the script.

I've added a test that replicates the issue and then fixed it.

@ruflin
Copy link
Owner

ruflin commented Aug 30, 2021

@dsgrillo Thanks for the contribution. Could you add a bit more description to your PR on what the issue is and how it is fixed?

@deguif
Copy link
Collaborator

deguif commented Aug 31, 2021

Here's what the documentation states about it regarding the link you posted.

Upsert

If the document does not already exist, the contents of the upsert element are inserted as a new document. If the document exists, the script is executed:
Scripted upsert

To run the script whether or not the document exists, set scripted_upsert to true:

@dsgrillo
Copy link
Contributor Author

dsgrillo commented Sep 3, 2021

Hi @deguif, thanks for making it clearer! 😄

In the context of upsert, scripts are usually used for making a partial update in the document, thus is usually not suitable to only use document for the insert, but start with a an "empty" and run the script for updating it to the desired state. Otherwise, there's a chance for a race condition and you might end up loosing one of the updates.

@@ -51,6 +51,7 @@ public function setScript(AbstractScript $script): AbstractDocument

if (!empty($upsert)) {
$source['upsert'] = $upsert;
$source['scripted_upsert'] = true;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To keep the option option to also set it to false I wonder if we should pass a second param to the setScript method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problem is that the setScript is called in the AbstractDocument. Don't think it makes much sense to mix the document and script here (in this case, adding one specific parameter of script).

Maybe adding it in the AbstractScript would be better?
So it becomes somehow similar to the implementation of doc_as_upsert.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we add it to AbstractScript, would it be also useful to the other classes or it doesn't make sense there?

Didn't fully get your comment related to doc_as_upsert. Can you share more?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the AbstractScript is used in other places, not only for bulk operations. I didn't reviewed all the cases, but I'm pretty confident that the scripted_upsert won't be expected for all of them. Having said that, we'd be using that parameter only within the bulk context.

What I meant with the doc_as_upsert is regarding the implementation above (lines 18-27 of the same file), where we check for the value of $document->getDocAsUpsert() and only then add it to the request.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsgrillo Sorry that this got stalled on my end. As you describe above, adding it to AbstractScript might not be ideal as it is not expected for all of them. So we are left with how to add it here.

What you propose with $document->getDocAsUpsert() sounds like a good path forward. If I understand this correct it means it would get the "value" from the doc itself and we would not need an additional param? I guess this requires that the document is set first?

@ruflin ruflin merged commit e479379 into ruflin:master Oct 25, 2021
@ruflin
Copy link
Owner

ruflin commented Oct 25, 2021

@dsgrillo Thank you for the contribution and sorry that it took so long to get this reviewed on my end. Somehow I missed that 21 days ago there were additional commits 🤦‍♂️

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

Successfully merging this pull request may close these issues.

3 participants