changing collection name

313 views
Skip to first unread message

Cem Caglar

unread,
Jul 9, 2019, 8:16:10 PM7/9/19
to RavenDB - 2nd generation document database
Hi,

Is there a way of changing the name of an existing collection with some records, as a migration script? (without deleting all records and creating them again)

What I did; 

foreach (var timeRecord in timeRecords)
 {
    // session.Store(timeRecord);
    var metadata = session.Advanced.GetMetadataFor(timeRecord);

    var oldId = metadata["@id"].ToString();
    var newId = oldId.Replace("TimeRecords", "CostRecords");


    metadata["@collection"] = "CostRecords";
    metadata["Raven-Clr-Type"] = "MyNamespace.TimeRecords.Persistence.CostRecord, MyNamespace";
    metadata["@id"] = newId;
    ....
    ....
    // then put / delete


This changes the id and metadata of each record, but collection name stays the same. 


Is there a nice way of changing the whole collection and its records to a new name?


Thanks
Cem

Grisha Kotler

unread,
Jul 10, 2019, 12:57:47 AM7/10/19
to rav...@googlegroups.com
Hi,

You need to recreate the documents with the new collection.

You can do it using a Patch:
from Orders
update {
    var documentId = id(this);
    del(documentId);
   
    this["@metadata"]["@collection"] = "New-Orders";
    put(documentId, this);
}

Grisha Kotler
Team Leader  /   Hibernating Rhinos LTD
Skype:  grisha.kotler
Support:  sup...@ravendb.net


--
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+u...@googlegroups.com.
To post to this group, send email to rav...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ravendb/2b023ab9-eee6-431a-8582-343c82c473c3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Cem Caglar

unread,
Jul 10, 2019, 1:34:39 AM7/10/19
to RavenDB - 2nd generation document database

Hi,

Thanks for the response. This code changes the metadata of each record, but doesn't update the existing collection name.

I need to (if possible) update the existing collection name without creating a new collection and/or inserting each record to it.


Cheers
Cem
To unsubscribe from this group and stop receiving emails from it, send an email to rav...@googlegroups.com.

Grisha Kotler

unread,
Jul 10, 2019, 1:57:18 AM7/10/19
to rav...@googlegroups.com
You can't change the collection name without delete/put.
The patch allows you to do that without having to load the document into the session.


Grisha Kotler
Team Leader  /   Hibernating Rhinos LTD
Skype:  grisha.kotler
Support:  sup...@ravendb.net

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

To post to this group, send email to rav...@googlegroups.com.

Alexander Klaus

unread,
Jul 10, 2019, 11:57:51 PM7/10/19
to RavenDB - 2nd generation document database
Hi Grisha,

I'm not OP, but work on the same project.

The ultimate goal is to reflect changed business requirements in the code and the database. They require a collection to have a different name (yep, it's a reflection of not having a proper ubiquitous language since the beginning).

What are the best practices to do that? 
We can't be the first to do that.

I see two issues with your suggestions:
  1. Modifying the metadata will fix mapping to the new data type on the client, but will keep the old name collection name in the database.
  2. To update the collection name we have to perform loop through all records and one-by-one do
    1. Load a record to the client
    2. Convert to a new type
    3. Save it to the new collection
    4. Delete the record from the old collection
Is there a way to do all the four steps on the server-side? There are commands to GET, PUT and DELETE, but it seems they'll require loading each item to the client.

 
Thank you in advance,
Alex

Grisha Kotler

unread,
Jul 11, 2019, 8:41:40 AM7/11/19
to rav...@googlegroups.com
Hi Aleksander,

You can do that by running a server-side patch.

The script below will change the collection name:

from Orders
update {
    var documentId = id(this);
    del(documentId);
    
    // change other properties in the document (you'll probably need to clone the document in order to do that).

    this["@metadata"]["@collection"] = "New-Orders";
    put(documentId, this);
}  

Grisha Kotler
Team Leader  /   Hibernating Rhinos LTD
Skype:  grisha.kotler
Support:  sup...@ravendb.net

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

To post to this group, send email to rav...@googlegroups.com.

Alexander Klaus

unread,
Jul 13, 2019, 8:18:00 PM7/13/19
to RavenDB - 2nd generation document database
Thanks Grisha, it worked.
Yes, we had to create another instance for sending to the put() method. Otherwise, it was complaining on changed vector.

On Thursday, July 11, 2019 at 10:41:40 PM UTC+10, Grisha Kotler wrote:
Hi Aleksander,

You can do that by running a server-side patch.

The script below will change the collection name:

from Orders
update {
    var documentId = id(this);
    del(documentId);
    
    // change other properties in the document (you'll probably need to clone the document in order to do that).
    this["@metadata"]["@collection"] = "New-Orders";
    put(documentId, this);
}  

Grisha Kotler
Team Leader  /   Hibernating Rhinos LTD
Skype:  grisha.kotler
Support:  sup...@ravendb.net


Alexander Klaus

unread,
Aug 29, 2019, 1:15:28 AM8/29/19
to RavenDB - 2nd generation document database
Found a problem in this approach - the @hilo collection wasn't renamed.
Therefore, on successful renaming of the collection when the I create the first next record the auto-generated ID would be New-Orders/1, which coincides with an already existing record.

How to resolve it? Rename the @hilo collection or drop the old one and manually create a new one?

Oren Eini (Ayende Rahien)

unread,
Aug 29, 2019, 3:34:23 AM8/29/19
to ravendb
The hilo records contain a document per collection, you can just remove the entry for the old record, no?

To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ravendb/00df1bca-4825-4f35-8394-ea34941dfee0%40googlegroups.com.


--
Oren Eini
CEO   /   Hibernating Rhinos LTD
Skype:  ayenderahien
Support:  sup...@ravendb.net

Alexander Klaus

unread,
Aug 29, 2019, 3:37:19 AM8/29/19
to RavenDB - 2nd generation document database
Removing the old one is easy.
But the new @hilo collection hasn't been created and when my C# code is calls session.Store(newRecord) ,the newRecord.Id gets initialised to NewCollection/1 and a record with this ID already exists.


On Thursday, August 29, 2019 at 5:34:23 PM UTC+10, Oren Eini wrote:
The hilo records contain a document per collection, you can just remove the entry for the old record, no?

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

Oren Eini (Ayende Rahien)

unread,
Aug 29, 2019, 3:38:13 AM8/29/19
to ravendb
Oh, you can just create a document with the same structure but a different id, and it will work

To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ravendb/ebe50341-3f0d-4a20-aee1-23dd42b73941%40googlegroups.com.

Alexander Klaus

unread,
Aug 29, 2019, 3:42:29 AM8/29/19
to RavenDB - 2nd generation document database
By using PutDocumentCommand (https://ravendb.net/docs/article-page/4.2/csharp/client-api/commands/documents/put)? Will it create the @metadata attribute or I have to specify it?


On Thursday, August 29, 2019 at 5:38:13 PM UTC+10, Oren Eini wrote:
Oh, you can just create a document with the same structure but a different id, and it will work

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

Oren Eini (Ayende Rahien)

unread,
Aug 29, 2019, 3:49:12 AM8/29/19
to ravendb
Set the metadata yourself, it won't do that on its own

To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ravendb/43f27955-d52a-4ec2-b4de-86309baafd98%40googlegroups.com.

Alexander Klaus

unread,
Aug 29, 2019, 3:57:36 AM8/29/19
to RavenDB - 2nd generation document database
Created a helper method to rename a hilo collection:
private void RenameHiLo(string oldHiLoCollectionName, string newHiLoCollectionName)
{
using (IDocumentSession session = DocumentStore.OpenSession(Database))
if (session.Advanced.Exists(oldHiLoCollectionName))
{
var getCommand = new GetDocumentsCommand(oldHiLoCollectionName, includes: null, metadataOnly: false);
session.Advanced.RequestExecutor.Execute(getCommand, session.Advanced.Context);
var hilo = (BlittableJsonReaderObject)getCommand.Result.Results[0];

var putCommand = new PutDocumentCommand(newHiLoCollectionName, null, hilo);
session.Advanced.RequestExecutor.Execute(putCommand, session.Advanced.Context);

session.Delete(oldHiLoCollectionName);
}
}

Do you see any pitfalls?



On Thursday, August 29, 2019 at 5:49:12 PM UTC+10, Oren Eini wrote:
Set the metadata yourself, it won't do that on its own

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

Oren Eini (Ayende Rahien)

unread,
Aug 29, 2019, 4:12:21 AM8/29/19
to ravendb
That would work, yes.


To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ravendb/a5e9cfb8-0ed7-4be7-ad5a-20f2e3090ead%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages