Delete item in dictionary with PatchRequest based on criteria

132 views
Skip to first unread message

marcus

unread,
Feb 20, 2018, 8:37:23 AM2/20/18
to RavenDB - 2nd generation document database
I have this document

{
    "IsDefaultCulture": false,
    "Name": "sv",
    "Culture": "sv",
    "Trie": {
        "/": {
            "ControllerName": "Home",
            "Name": "Hem",
            "PageId": "homes/290-A"
        },
        "/om-oss": {
            "ControllerName": "About",
            "Name": "Om oss",
            "PageId": "abouts/290-A"
        },
        "/om-oss-2": {
            "Name": "Om oss 2",
            "PageId": "abouts/321-A",
            "ControllerName": "About"
        }
    },
    "@metadata": {
        "@collection": "Sites",
        "Raven-Clr-Type": "src.Site, src"
    }
}

and I need to remove an item from the Trie using a PatchRequest based on the PageId property.

How can I write the Script and select the item with PageId abouts/290-A and remove that item from the dictionary?

marcus

unread,
Feb 20, 2018, 3:45:59 PM2/20/18
to RavenDB - 2nd generation document database
In RavenDB 3.5 I think the correct way of doing this is to use RemoveWhere in the patch. Is this possible to do in RavenDB 4 or has this part changed in any way?

This is what I try to do.

                PatchCommandData patchCommandData = new PatchCommandData($"sites/{requestCultureFeature.RequestCulture.Culture.Name}", null, new PatchRequest
                {
                  Script = @"this.Trie.RemoveWhere(function(node) {{
                    return node.PageId == args.PageId;
                  }});",
                  Values =
                  {
                      { "PageId", $"{args.DocumentId}" }
                  }
                }, null);

                ((IAsyncDocumentSession)args.Session).Advanced.Defer(patchCommandData);

But this ends upp with the following exception:

An unhandled exception occurred while processing the request.
JavaScriptException: Raven.Client.Exceptions.Documents.Patching.JavaScriptException: At 0:4
{"name":"TypeError","message":"Object has no method 'RemoveWhere'","callstack":" at RemoveWhere(Esprima.Ast.FunctionExpression) @ 0:4\n at call(doc, args) @ 4:11\n"} ---> Jint.Runtime.JavaScriptException: Object has no method 'RemoveWhere'
at Jint.Native.Function.ScriptFunctionInstance.Call(JsValue thisArg, JsValue[] arguments)
at Raven.Server.Documents.Patch.ScriptRunner.SingleRun.Run(DocumentsOperationContext ctx, String method, Object[] args) in C:\work\ravendb-4.0\src\Raven.Server\Documents\Patch\ScriptRunner.cs:line 587
--- End of inner exception stack trace ---
at Raven.Server.Documents.Patch.ScriptRunner.SingleRun.Run(DocumentsOperationContext ctx, String method, Object[] args) in C:\work\ravendb-4.0\src\Raven.Server\Documents\Patch\ScriptRunner.cs:line 601
at Raven.Server.Documents.Patch.PatchDocumentCommand.Execute(DocumentsOperationContext context) in C:\work\ravendb-4.0\src\Raven.Server\Documents\Patch\PatchDocumentCommand.cs:line 140
at Raven.Server.Documents.Handlers.BatchHandler.MergedBatchCommand.Execute(DocumentsOperationContext context) in C:\work\ravendb-4.0\src\Raven.Server\Documents\Handlers\BatchHandler.cs:line 344
at Raven.Server.Documents.TransactionOperationsMerger.ExecutePendingOperationsInTransaction(List`1 pendingOps, DocumentsOperationContext context, Task previousOperation, DurationMeasurement& meter) in C:\work\ravendb-4.0\src\Raven.Server\Documents\TransactionOperationsMerger.cs:line 597
at Raven.Server.Documents.TransactionOperationsMerger.MergeTransactionsOnce() in C:\work\ravendb-4.0\src\Raven.Server\Documents\TransactionOperationsMerger.cs:line 307
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Raven.Server.Documents.TransactionOperationsMerger.<Enqueue>d__22.MoveNext() in C:\work\ravendb-4.0\src\Raven.Server\Documents\TransactionOperationsMerger.cs:line 89
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Raven.Server.Documents.Handlers.BatchHandler.<BulkDocs>d__0.MoveNext() in C:\work\ravendb-4.0\src\Raven.Server\Documents\Handlers\BatchHandler.cs:line 54
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Raven.Server.Routing.RequestRouter.<HandlePath>d__6.MoveNext() in C:\work\ravendb-4.0\src\Raven.Server\Routing\RequestRouter.cs:line 97
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
at Raven.Server.RavenServerStartup.<RequestHandler>d__11.MoveNext() in C:\work\ravendb-4.0\src\Raven.Server\RavenServerStartup.cs:line 159
Raven.Client.Exceptions.ExceptionDispatcher+<Throw>d__3.MoveNext() in C:\Builds\RavenDB-Stable-4.0\src\Raven.Client\Exceptions\ExceptionDispatcher.cs, line 117

Oren Eini (Ayende Rahien)

unread,
Feb 21, 2018, 2:58:39 AM2/21/18
to ravendb
  PatchCommandData patchCommandData = new PatchCommandData($"sites/{requestCultureFeature.RequestCulture.Culture.Name}", null, new PatchRequest
                {
                  Script = @" this.Trie  = this.Trie.filter(function(node) {{
                    return node.PageId != args.PageId;
                  }});",
                  Values =
                  {
                      { "PageId", $"{args.DocumentId}" }
                  }
                }, null);

                ((IAsyncDocumentSession)args.Session).Advanced.Defer(patchCommandData);


Hibernating Rhinos Ltd  

Oren Eini l CEO Mobile: + 972-52-548-6969

Office: +972-4-622-7811 l Fax: +972-153-4-622-7811

 


--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

marcus

unread,
Feb 21, 2018, 3:08:44 AM2/21/18
to RavenDB - 2nd generation document database
Filter does not seem to exist either?

I'm using  4.0.1-custom-40 on the server and 4.0.0 on the client

Here is the exception:

An unhandled exception occurred while processing the request.
JavaScriptException: Raven.Client.Exceptions.Documents.Patching.JavaScriptException: At 1:4
{"name":"TypeError","message":"Object has no method 'filter'","callstack":" at filter(Esprima.Ast.FunctionExpression) @ 14:4\n at call(doc, args) @ 4:11\n"} ---> Jint.Runtime.JavaScriptException: Object has no method 'filter'
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.

Vincent Van Mulders

unread,
Feb 21, 2018, 3:37:12 AM2/21/18
to RavenDB - 2nd generation document database
Isn't Trie a map/object here instead of an array?

Oren Eini (Ayende Rahien)

unread,
Feb 21, 2018, 3:48:42 AM2/21/18
to ravendb
Oh, sorry, I assumed Trie is an array.
Looks like there is an issue with iterating over documents (http://issues.hibernatingrhinos.com/issue/RavenDB-10571).

To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

marcus

unread,
Feb 21, 2018, 3:54:28 AM2/21/18
to RavenDB - 2nd generation document database
Ok, I tried Object.keys but I didn't get any exception. Are you working on this in the near future?

Oren Eini (Ayende Rahien)

unread,
Feb 21, 2018, 3:55:48 AM2/21/18
to ravendb
Yes, we'll have a solution soon
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

Oren Eini (Ayende Rahien)

unread,
Feb 21, 2018, 5:32:40 AM2/21/18
to ravendb
Okay, we didn't mark the properties as enumerable, so that caused the issue.
Fixed now and will be in the next nightly

marcus

unread,
Feb 21, 2018, 7:32:28 AM2/21/18
to RavenDB - 2nd generation document database
With this fix, will it be possible to delete an item like this?

                PatchCommandData patchCommandData = new PatchCommandData($"sites/{requestCultureFeature.RequestCulture.Culture.Name}", null, new PatchRequest
                {
                  Script = @" Object.keys(this.Trie).filter(function(key) {{
                    if(this.Trie[key].PageId === args.PageId) {{
                      delete this.Trie[key];
                    }}
                  }});",
                  Values =
                  {
                      { "PageId", $"{args.DocumentId}" }
                  }
                }, null);

                ((IAsyncDocumentSession)args.Session).Advanced.Defer(patchCommandData);

Oren Eini (Ayende Rahien)

unread,
Feb 21, 2018, 7:36:17 AM2/21/18
to ravendb
Yes, that should work.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

marcus

unread,
Feb 21, 2018, 11:24:49 AM2/21/18
to RavenDB - 2nd generation document database
Was this fix included in this version: 4.0.2-nightly-20180221-0501?

I tried to delete an entry in my dictionary but it does not get deleted.

This is what I send to the server:

Oren Eini (Ayende Rahien)

unread,
Feb 21, 2018, 11:26:11 AM2/21/18
to ravendb
key is not defined here.
You need args.key or $key (IIRC)
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

Oren Eini (Ayende Rahien)

unread,
Feb 21, 2018, 11:26:58 AM2/21/18
to ravendb
And I think you'll need tomorrow's nightly

marcus

unread,
Feb 21, 2018, 11:29:07 AM2/21/18
to RavenDB - 2nd generation document database
What do you mean? key is the parameter to the function and args.PageId is what I use to identify the correct entry

Oren Eini (Ayende Rahien)

unread,
Feb 22, 2018, 3:58:37 AM2/22/18
to ravendb
Blah, sorry, didn't see that.
In this case, the problem is that the this pointer is different inside the filter function. You can use:

var self = this;
Object.keys(this.Trie).filter(function(key) {
    if(self.Trie[key].PageId === args.PageId) {
        delete self.Trie[key];
    }
});

And this will work.

To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

marcus

unread,
Feb 22, 2018, 5:41:13 AM2/22/18
to RavenDB - 2nd generation document database
This seems to work as expected with the latest nightly.

The arrow function should also work but my test fails if I change to an arrow function?

                      Object.keys(this.Trie).filter((key) => {
                          if(this.Trie[key].PageId === args.PageId) {
                              delete this.Trie[key];
                          }
                      });

Oren Eini (Ayende Rahien)

unread,
Feb 22, 2018, 6:14:12 AM2/22/18
to ravendb
Same "self != this" issue, I think?
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

marcus

unread,
Feb 22, 2018, 8:01:46 AM2/22/18
to RavenDB - 2nd generation document database
No, arrow functions does not have it's own this so I think it is a bug if you have decided to support arrow functions

Oren Eini (Ayende Rahien)

unread,
Feb 22, 2018, 8:04:45 AM2/22/18
to ravendb
It is probably bug in the scope handling in Jint, yes
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages