3
votes

I have a Model called Post, which has a field called Slug. I've marked this field with the attribute [ID] and changed the FindIdentityProperty Convention in RavenDB such that it considers the property marked with [ID] as the Identity of the document.

Now I want to fetch all posts that have slugs that start with the character G, do I need to create an index like this :

from Post in docs.Posts
select new { Slug = Post.Slug }

or like this

from Post in docs.Posts
select new { Id = Post.Id }

or do I use the index that RavenDB internally should have since I'm querying on ID. I understand that RavenDB has the ID property indexed somewhere so that a Session.Load<Post>("SomeID") is possible.

The 1st option can be defined in code in C# as an AbstractIndexCreationTask because C# understands that Slug is a field of Post, but does not work as it is "string"ified into RavenDB like this : (when Index Creation happens)

from Post in docs.Posts
select new { Slug = Post.Slug }

becomes

docs.Posts
    .Select(Post => new {Slug = Post.Slug })

You can see this when you look in the SL-UI, after indexes are created.

And this does NOT work because ( as shown in the SL-UI of the DB ) the JSON representation of the Post, there is no name-value pair like "Slug":"Some-Slug". Since it's the ID it is shown above the document, and in the @metadata it can be seen as the value of _document_id

The latter one does work, but only when defined as a string, like this in C#

public class Post_ById : AbstractIndexCreationTask
    {
        public override IndexDefinition CreateIndexDefinition()
        {
            return new IndexDefinition
                       {
                           Map = "from Post in docs.Posts select new { Id = Post.Id}"
                       };
        }
    }

I suspect when Raven gets queries that contain the string "Id", it automatically takes it to mean that it's a query on [@metadata][_document_id].

No LINQ goodness here - looks very brittle, won't survive a refactor of the domain name. Id is not a field of Post, but this index did allow me to do what I wanted, namely, "fetch all posts that have slugs that start with the character G". And I hate defining indexes for Ids when DB should already have such an index.

1

1 Answers

3
votes

Hm, we actually use the same conventions in AbstractIndexCreationTask as well, so that should work. At any rate, the id of the document can always be accessed using __document_id