Querying by DateTime.Ticks not working?

176 views
Skip to first unread message

Marcelo Volmaro

unread,
Dec 6, 2015, 11:35:01 AM12/6/15
to RavenDB - 2nd generation document database
Hi,
As per a discussion here, I changed one of my indexes to use DateTime.Ticks instead of DateTime, in order to gain some processing speed/memory reductions while ordering the results of my query.

The old index was:
public sealed class DebugMessages_ByDefaultIndexes : AbstractIndexCreationTask<DebugMessage>
{
public DebugMessages_ByDefaultIndexes()
{
Map = messages => messages
.Select(item => new
{
item.OccurredOn,
item.ApplicationName,
item.Type
});
}
}

And now the new index is:
public sealed class DebugMessages_ByDefaultIndexes : AbstractIndexCreationTask<DebugMessage>
{
public DebugMessages_ByDefaultIndexes()
{
Map = messages => messages
.Select(item => new
{
item.OccurredOn.Ticks,
item.ApplicationName,
item.Type
});
Sort(x => x.OccurredOn.Ticks, SortOptions.Long);
}
}

Where OccuredOn is a property of type DateTime. And so, I changed my query from "iRavenQueryable.Where(x => x.OccurredOn <= occurredBefore)" to "iRavenQueryable.Where(x => x.OccurredOn.Ticks <= occurredBefore.Ticks)". 
Now, I'm not getting any results from that query. (I suppose I don't need to say that I recreated the DB - This is still a test project I'm working on so I can destroy/recreate my DB at any time). Of course, using the first index/query worked just fine.

I'm doing something wrong here? (The Sort clause on the second index is because I also need to sort via that field).


Chris Marisic

unread,
Dec 6, 2015, 4:41:38 PM12/6/15
to RavenDB - 2nd generation document database
I would add a first class property to your model

item { long Ticks { get { return OccuredOn.Ticks; } }

if you do this, you will need to load and save all documents, or patch it in.

Marcelo Volmaro

unread,
Dec 6, 2015, 8:01:58 PM12/6/15
to RavenDB - 2nd generation document database
Well, that worked, thanks!, now... should I consider this a bug? The only difference is the name of the field's index...

Oren Eini (Ayende Rahien)

unread,
Dec 7, 2015, 3:50:38 AM12/7/15
to ravendb
The issue is here:

Map = messages => messages
.Select(item => new
{
item.OccurredOn.Ticks, // Generate a field named Ticks
});


Sort(x => x.OccurredOn.Ticks, SortOptions.Long); // Assumes you meant to have a field OccuredOn_Ticks



Hibernating Rhinos Ltd  

Oren Eini l CEO Mobile: + 972-52-548-6969

Office: +972-4-622-7811 l Fax: +972-153-4-622-7811

 


--
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.
For more options, visit https://groups.google.com/d/optout.

Marcelo Volmaro

unread,
Dec 7, 2015, 9:28:03 AM12/7/15
to RavenDB - 2nd generation document database
Ok, but that makes no sense... Why the first one will generate a field named Ticks, while the second one will mean OccuredOn_Ticks? I believe the second one is right, the first one it is not.
So, manually naming the field on the index should work then?

Oren Eini (Ayende Rahien)

unread,
Dec 7, 2015, 9:44:56 AM12/7/15
to ravendb
It has to do with who is doing this.
item.OccurredOn.Ticks, // Generate a field named Ticks

The name is generated using C# compiler.

You are expected to generate it using:

OccurredOn_Ticks = item.OccurredOn.Ticks, // Generate a field named Ticks

Chris Marisic

unread,
Dec 7, 2015, 11:22:29 AM12/7/15
to RavenDB - 2nd generation document database


On Monday, December 7, 2015 at 8:44:56 AM UTC-6, Oren Eini wrote:

You are expected to generate it using:

OccurredOn_Ticks = item.OccurredOn.Ticks, // Generate a field named Ticks



You really need to do something about this. I understand what's going on here from being here so long but almost no one else can obviously see why it should be that.

I don't really know what to do but i think with raven's parser that 

item.OccurredOn.Ticks should always generate OccurredOn_Ticks  unless you do 

new {
SomeCustomName = item.OccurredOn.Ticks 

Kijana Woodard

unread,
Dec 7, 2015, 11:35:09 AM12/7/15
to rav...@googlegroups.com
+1

I was going to answer the question with the technically correct answer, but I couldn't summon a decent reason to explain the behavior without resorting to technical explanations. If the technical challenges are insurmountable, then I suppose the documentation would have to be painfully clear as to what to do.

One "reasonable" approach is to always name properties and to always use an "Input/Query/Map" class when addressing the index as opposed to the document class itself. Of course that diminishes some of the RAD characteristics of the client API.

--

Marcelo Volmaro

unread,
Dec 7, 2015, 1:15:33 PM12/7/15
to RavenDB - 2nd generation document database
Well, that was my first thought... And what I tried. I created an internal class to hold the indexes names, but then I found that when querying, even if I specify the index, I'm querying the document's properties, not the index properties, so it was impossible to do my query as the indexed fields where not available to use on the Where, OrderBy, etc...

Kijana Woodard

unread,
Dec 7, 2015, 1:38:28 PM12/7/15
to rav...@googlegroups.com
I don't know if there's a canonical example, but here's a common pattern [WARNING: gmail code]:

public class FooIndex : Abstract....{
   public class Query {
     public string Search { get; set; }
   }

   public FooIndex() {
       Map = docs =>
                from doc in docs
                select new
                {
                    Search = new[] { doc.Name, doc.CompanyName }
                };
   }
}

...then...

var result = DocumentSession.Query<FooIndex.Query, FooIndex>()
                                    .Search(x => x.Search, search)
                                    .As<Foo>()
                                    .ToList()

Replace or augment Search with Where, OrderBy, etc.
The "As" call will coerce to the document type, which is what you will be getting back from session.Query.

Oren Eini (Ayende Rahien)

unread,
Dec 8, 2015, 3:50:43 AM12/8/15
to ravendb
I wish we would have thought of that, but at this point, there are a LOT of code that rely on this behavior, and it would be a silent breaking change that would kill the system when you upgrade it.

Hibernating Rhinos Ltd  

Oren Eini l CEO Mobile: + 972-52-548-6969

Office: +972-4-622-7811 l Fax: +972-153-4-622-7811

 


--

Chris Marisic

unread,
Dec 8, 2015, 10:50:38 AM12/8/15
to RavenDB - 2nd generation document database
The solution to that is mark the indexes as legacy mode during platform upgrades and use the current behavior 

Marcelo Volmaro

unread,
Dec 8, 2015, 11:01:36 AM12/8/15
to RavenDB - 2nd generation document database
Or do a breaking change so IF you upgrade, your code doesn't compile anymore. Drastic, yes. But Microsoft did that with EF, Asp.MVC, etc... and nobody is whining about that. There are associated costs if you want a better/faster/safer version of any piece of software, and if you are not willing to pay for them, you can simply don't upgrade.

Oren Eini (Ayende Rahien)

unread,
Dec 8, 2015, 11:08:54 AM12/8/15
to ravendb
That is something that we are considering for 4.0, but that will be a whil eyet.

Hibernating Rhinos Ltd  

Oren Eini l CEO Mobile: + 972-52-548-6969

Office: +972-4-622-7811 l Fax: +972-153-4-622-7811

 


On Tue, Dec 8, 2015 at 6:01 PM, Marcelo Volmaro <mvol...@gmail.com> wrote:
Or do a breaking change so IF you upgrade, your code doesn't compile anymore. Drastic, yes. But Microsoft did that with EF, Asp.MVC, etc... and nobody is whining about that. There are associated costs if you want a better/faster/safer version of any piece of software, and if you are not willing to pay for them, you can simply don't upgrade.

--

Chris Marisic

unread,
Dec 8, 2015, 11:13:38 AM12/8/15
to RavenDB - 2nd generation document database
I wholeheartedly support breaking changes on major versions that really fix things as long as the breaking change is communicated properly through build failures error messages.

The worst breaking change is "<type> does not contain a definition for 'Foo' and no extension method 'Foo"....." 

Oren Eini (Ayende Rahien)

unread,
Dec 8, 2015, 11:15:58 AM12/8/15
to ravendb
Can you expand on that?

Hibernating Rhinos Ltd  

Oren Eini l CEO Mobile: + 972-52-548-6969

Office: +972-4-622-7811 l Fax: +972-153-4-622-7811

 


--

Chris Marisic

unread,
Dec 8, 2015, 11:32:36 AM12/8/15
to RavenDB - 2nd generation document database
That's the standard complier error for a method just doesn't exist. Usually this happens in regular coding if you just typo a method signature instead of using autocomplete. The bad breaking change version is the library itself removed/renamed/altered the arguments that method and all existing calls get a build failure with no information. Where the good breaking change "Foo is obsolete, do XXXXXXXXXXXXX"
Reply all
Reply to author
Forward
0 new messages