Question about the default Identity naming logic

153 views
Skip to first unread message

Justin A

unread,
Mar 2, 2012, 2:05:42 AM3/2/12
to rav...@googlegroups.com
Hi folks.

i've noticed the following happens with how raven db generates the first 'name' part of a Stored identity.

class Cat
cats/1
cats/2
..

but if the class is like this..
class CatsAndDogs
CatsAndDogs/1
CatsAndDogs/2

is this the standard practice? 

I know i can overwrite this by

class CatsAndDogs
{
    Id = "catsAndDogs"
}

but i thought that the standard was all lowercase?

Oren Eini (Ayende Rahien)

unread,
Mar 2, 2012, 2:49:17 AM3/2/12
to rav...@googlegroups.com
If you have just a capital letter, we lower case it.
If you have multiple, we preserve casing. 
This is because most pof the time, you have only one capital, and if you have more, it is usually to have some meaning with regards to that.

Justin A

unread,
Mar 2, 2012, 4:33:12 AM3/2/12
to rav...@googlegroups.com
great, thanks :)

Justin A

unread,
Mar 8, 2012, 8:56:06 AM3/8/12
to rav...@googlegroups.com
Sorry to cast the spell 'raise-dead' on this thread, but I was looking through the docs and noticed this :-


quote: We left the "Id" property of BlogPost blank, and it is this property that will be used as the "primary key" for this document. RavenDB generated an id for us, "blogposts/1", based on the default convention. 

shouldn't that be "BlogPosts/1" ?

Lastly, there's no mention of the syntax if we want to define our own Id's. Just to clarify, if we want blogPosts/1, do I set the Id value to "blogPosts" or "blogPosts/" (where RavenDb will magically know what number to add to the end)

Oren Eini (Ayende Rahien)

unread,
Mar 9, 2012, 5:34:41 AM3/9/12
to rav...@googlegroups.com
Justin,
We will fix the docs.
And you can change that by modifying Conventions.TransformTypeTagNameToDocumentKeyPrefix

Itamar Syn-Hershko

unread,
Mar 11, 2012, 11:38:20 AM3/11/12
to rav...@googlegroups.com
Lastly, there's no mention of the syntax if we want to define our own Id's. Just to clarify, if we want blogPosts/1, do I set the Id value to "blogPosts" or "blogPosts/" (where RavenDb will magically know what number to add to the end)

Justin, we actually do discuss this, see here http://ravendb.net/docs/client-api

I'm refactoring the discussion there a bit tho, so it will be easier to read and understand...

Justin A

unread,
Mar 13, 2012, 12:09:45 AM3/13/12
to rav...@googlegroups.com
Ah yes - there is some mention of it! nice :)

question ..

RavenDB also supports the notion of Identity, if you need ids to be consecutive, or when you want to specify a key name that is different from what RavenDB will produce for you. By creating a string Id property in your entity, and setting it to a value ending with a slash (/), you can tell RavenDB to use that as a key perfix for your entity. That prefix followed by the next available integer id for it will be your entity's id after you call SaveChanges(). 

So is this saying
1. If you want to use an Identity (ie. every new item saved will ask RavenDb for the next avail id, instead of using a HiLo range), then you set the Id property to: whatever + "/"
2. If you want -every- document for -any- collection, to use Identity (instead of HiLo), then set the Convention: store.Conventions.DocumentKeyGenerator = entity => store.Conventions.GetTypeTagName(entity.GetType()) +"/";

This means you cannot use HiLo -and- custom Document Key/Id names?

Oren Eini (Ayende Rahien)

unread,
Mar 13, 2012, 6:51:22 AM3/13/12
to rav...@googlegroups.com
inline

On Tue, Mar 13, 2012 at 6:09 AM, Justin A <jus...@adler.com.au> wrote:
Ah yes - there is some mention of it! nice :)

question ..

RavenDB also supports the notion of Identity, if you need ids to be consecutive, or when you want to specify a key name that is different from what RavenDB will produce for you. By creating a string Id property in your entity, and setting it to a value ending with a slash (/), you can tell RavenDB to use that as a key perfix for your entity. That prefix followed by the next available integer id for it will be your entity's id after you call SaveChanges(). 

So is this saying
1. If you want to use an Identity (ie. every new item saved will ask RavenDb for the next avail id, instead of using a HiLo range), then you set the Id property to: whatever + "/"

Yes
 
2. If you want -every- document for -any- collection, to use Identity (instead of HiLo), then set the Convention: store.Conventions.DocumentKeyGenerator = entity => store.Conventions.GetTypeTagName(entity.GetType()) +"/";


Yes
 
This means you cannot use HiLo -and- custom Document Key/Id names?


I don't understand this question. You generally don't mix id generation strategies.

Justin A

unread,
Mar 13, 2012, 7:02:45 AM3/13/12
to rav...@googlegroups.com
This means you cannot use HiLo -and- custom Document Key/Id names?


I don't understand this question. You generally don't mix id generation strategies.

What I was trying to say was if I have two collections, Users and .. um .. Products ... I can use HiLo for Users, but Products can be via Identity. 

BUT, if i wanted to have the Users collection be HiLo -and- for me to define the Id as .. PewPew/ ... <-- I can't do that. If u want HiLo, then u need to let RavenDb define the -entire- Id value, the string part AND the number part. 

Is that correct?

-----

On a side note, are the string Id's case sensitive? 
Is a Users/1 document and a users/1 document the same document? case is irrelevant?

Oren Eini (Ayende Rahien)

unread,
Mar 13, 2012, 7:06:02 AM3/13/12
to rav...@googlegroups.com
No,
You can do that in the  DocumentKeyGenerator  
You just need to modify you logic based on whatever it is that you are using to determine that

Oren Eini (Ayende Rahien)

unread,
Mar 13, 2012, 7:06:17 AM3/13/12
to rav...@googlegroups.com
Ids are case INsensitive.

On Tue, Mar 13, 2012 at 1:02 PM, Justin A <jus...@adler.com.au> wrote:

Maverix

unread,
Apr 11, 2012, 12:33:50 AM4/11/12
to ravendb
I have found a minor bug regarding HiLo generated id numbers.
in the tests below ComplexTest1 will fail because of a casing issue.

When the session loads using an integer -->
session.Load<ComplexClass>(1);
the returned document has the id set to "complexclasses/1"

whereas when the session loads using "ComplexClasses/1"
the returned document has the id set to "ComplexClasses/1"

As you have already said Oren, RavenDB is case insensitive.
But it could lead to subtle gotcha if strings are compared in the
calling application code elsewhere and dont expect this.

I couldn't find an existing test case.


protected EmbeddableDocumentStore Store() {
var documentStore = new EmbeddableDocumentStore {
RunInMemory = true
};
documentStore.Initialize();
return documentStore;
}

public class Simple {
public string Id { get; set; }
}

[TestMethod()]
public void SimpleTest1() {
Simple item = new Simple { };

using (IDocumentStore store = Store()) {
using (var session = store.OpenSession()) {
session.Store(item);
session.SaveChanges();
}

using (var session = store.OpenSession()) {
Simple stored = session.Load<Simple>(1);
Assert.IsNotNull(stored);
Assert.AreEqual(stored.Id, "simples/1");
}
}
}

[TestMethod()]
public void SimpleTest2() {
Simple item = new Simple { };

using (IDocumentStore store = Store()) {
using (var session = store.OpenSession()) {
session.Store(item);
session.SaveChanges();
}

using (var session = store.OpenSession()) {
Simple stored = session.Load<Simple>("simples/1");
Assert.IsNotNull(stored);
Assert.AreEqual(stored.Id, "simples/1");
}
}
}

public class ComplexClass {
public string Id { get; set; }
}

[TestMethod()]
public void ComplexTest1() {
ComplexClass item = new ComplexClass { };

using (IDocumentStore store = Store()) {
using (var session = store.OpenSession()) {
session.Store(item);
session.SaveChanges();
}

using (var session = store.OpenSession()) {
ComplexClass stored = session.Load<ComplexClass>(1);
Assert.IsNotNull(stored);
Assert.AreEqual(stored.Id, "ComplexClasses/1");
}
}
}

[TestMethod()]
public void ComplexTest2() {
ComplexClass item = new ComplexClass { };

using (IDocumentStore store = Store()) {
using (var session = store.OpenSession()) {
session.Store(item);
session.SaveChanges();
}

using (var session = store.OpenSession()) {
ComplexClass stored =
session.Load<ComplexClass>("ComplexClasses/1");
Assert.IsNotNull(stored);
Assert.AreEqual(stored.Id, "ComplexClasses/1");
}
}
}

Oren Eini (Ayende Rahien)

unread,
Apr 11, 2012, 5:05:57 AM4/11/12
to rav...@googlegroups.com
Thanks for the test, fixed and will be in the next build.

Justin A

unread,
Apr 12, 2012, 2:01:49 AM4/12/12
to rav...@googlegroups.com
wow! thanks heaps Maverix :) i think this was the error i was getting too .. but failed miserably to explain it *blush*.

Wootsies :)
Reply all
Reply to author
Forward
0 new messages