Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,125 | Comments: 45,488

filter by tags archive

Raven’s Scripted Index Results

time to read 2 min | 317 words

Scripted Index Results (I wish it would have a better name) is a really interesting new feature in RavenDB 2.5. As the name implies, it allows you to attach scripts to indexes. Those scripts can operate on the results of the indexing.

Sounds boring, right? But the options that is opens are nothing but. Using Scripted Index Results you can get recursive map/reduce indexes, for example. But we won’t be doing that today. Instead, I’ll show how you can enhance entities with additional information from other sources.

Our sample database is Northwind, and we have defined the following index to get some statistics about our customers:


And we can query it like this:


However, what we want to do is to be able to embed those values inside the company document, so we won’t have to query for it separately. Here is how we can use the new Scripted Index Results bundle to do this:


Once we have defined that, whenever the index is done, it will run these scripts, and that, in turns, means that this is what our dear ALFKI looks like:


I’ll leave recursive map/reduce as tidbit for my dear readers Smile.


Khalid Abuhakmeh

I have a few questions about this feature:

  1. What makes this better than using a transformer?
  2. What kind of performance hit does this put on the indexing process?

I'm sure I will have more, but those are the first two that come to mind.

Ayende Rahien

Khalid, 1) This happens during indexing, and they can update document(s), so you can index those items. 2) It would slow down a bit, but I don't expect it to be too much.

Khalid Abuhakmeh

Your answer to question one seems very interesting. So how do you handle this scenario?

  1. An Order is added.
  2. Orders/ByCompany is updated, which updates the Companies collection.

Does step 2 have to run all indexes again, and can you cause a weird cyclical issue with indexes, where they will constantly be running?

Index A is dependent on Collection A and updates Collection B, and Index B is dependent on collection B which updates Collection A.

How do you prevent something like that from happening, or at least warn the developer that they are doing something stupid?

Ayende Rahien

Companies doc gets updated, the relevant indexes gets run. You cannot modify a document that will be indexed by the same index that trigger this operation. The reason for that is to avoid infinite recursion.

If you have it in two indexes, yes, you have a problem.

Khalid Abuhakmeh

Do you and the team have any ideas on how to prevent someone from shooting themselves in the foot, or is that just accepted as collateral damage?

It seems like an issue that could be common across a development team. Two developers could be working on separate but related features on separate branches, where the issue would manifest after the two features were merged into the same branch.

Ayende Rahien

Khalid, I don't know how to handle that scenario, in order to do that, you would have to keep track of every action by every index for all time. We keep track of that for a single index, though.

Khalid Abuhakmeh

I am just thinking out loud, but what if during the indexing process you also tracked the source of what caused that indexing to happen?

  • External Document Put
  • Internal Document Put (script) with Source

You could do pattern matching based on Index, Source, Document Id that caused the index, and frequency within a certain time. If you hit a threshold, you can log a warning in the Management Studio. In addition, you could stop the indexes to save the system.

"Woah we sure touched this one document a lot within a certain time, and it seems what is affecting it is internal to RavenDB, we think there might be something wrong with these indexes: {Index}, {Source}."

You don't have to save this data for a long period of time, you just need a buffered window according to your frequency window (1 minute)? If an item falls out of the window, just throw away that info. Funny enough I think this is a good use case for your previous idea of an event stream.

Not sure if this is possible, just thinking out loud.

Ayende Rahien

Khalid, And now you need to track a WHOLE lot of information in the system. Not only that, but you need to track the source of each write, and it is pretty expensive and hard to do. For something that is purely theoretical right now.

Also, there might be valid reasons why you would want to do that (if you know that you do recursion only to a certain level, for example).



but the Orders class with count and total in the main document should be already be there and empty in the .NET class?

If not how those information will be deserialized?

Ayende Rahien

Simone, If the properties aren't there, they will be ignored and removed on the next save.

Comment preview

Comments have been closed on this topic.


  1. The design of RavenDB 4.0: Physically segregating collections - 8 hours from now
  2. RavenDB 3.5 Whirlwind tour: I need to be free to explore my data - about one day from now
  3. RavenDB 3.5 whirl wind tour: I'll have the 3+1 goodies to go, please - 4 days from now
  4. The design of RavenDB 4.0: Voron has a one track mind - 5 days from now
  5. RavenDB 3.5 whirl wind tour: Digging deep into the internals - 6 days from now

And 12 more posts are pending...

There are posts all the way to May 30, 2016


  1. The design of RavenDB 4.0 (14):
    03 May 2016 - Making Lucene reliable
  2. RavenDB 3.5 whirl wind tour (14):
    04 May 2016 - I’ll find who is taking my I/O bandwidth and they SHALL pay
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats