title: RavenDB Querying on ID
body: <p>I have a Model called <strong>Post</strong>, which has a field called <strong>Slug</strong>. 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.</p>
  
  <p>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 :</p>
  
  <pre><code>from Post in docs.Posts
  select new { Slug = Post.Slug }
  </code></pre>
  
  <p>or like this</p>
  
  <pre><code>from Post in docs.Posts
  select new { Id = Post.Id }
  </code></pre>
  
  <p>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 <code>Session.Load&lt;Post&gt;("SomeID")</code> is possible.</p>
  
  <p>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)</p>
  
  <pre><code>from Post in docs.Posts
  select new { Slug = Post.Slug }
  </code></pre>
  
  <p>becomes</p>
  
  <pre><code>docs.Posts
      .Select(Post =&gt; new {Slug = Post.Slug })
  </code></pre>
  
  <p>You can see this when you look in the SL-UI, after indexes are created.</p>
  
  <p>And this does <strong>NOT</strong> work because ( as shown in the SL-UI of the DB ) the JSON representation of the Post, there is no name-value pair like <code>"Slug":"Some-Slug"</code>. Since it's the ID it is shown <em>above</em> the document, and in the @metadata it can be seen as the value of <strong>_document_id</strong> </p>
  
  <p>The latter one does work, but only when defined as a string, like this in C#</p>
  
  <pre><code>public class Post_ById : AbstractIndexCreationTask
      {
          public override IndexDefinition CreateIndexDefinition()
          {
              return new IndexDefinition
                         {
                             Map = "from Post in docs.Posts select new { Id = Post.Id}"
                         };
          }
      }
  </code></pre>
  
  <p>I suspect when Raven gets queries that contain the string "<strong>Id</strong>", it automatically takes it to mean that it's a query on <strong>[@metadata][_document_id]</strong>.</p>
  
  <p>No LINQ goodness here - looks very brittle, won't survive a refactor of the domain name. <strong>Id</strong> is not a field of Post, but this index did allow me to do what I wanted, namely, "<em>fetch all posts that have slugs that start with the character G</em>". And I hate defining indexes for Ids when DB should already have such an index.</p>