Re: [RavenDB] When transformer is applied, ID field comes back all lower case (Version 2.5.Stable build 2700)

212 ikustaldi
Joan irakurri gabeko lehen mezura

Oren Eini (Ayende Rahien)

irakurri gabe,
2013(e)ko ira. 29(a) (04:44:49)13/9/29
Hartzailea: ravendb
Yes, this is by design.
When you use Id from a transformer, we get the lower cased id stored in the index.


On Sat, Sep 28, 2013 at 9:51 PM, Tom Cabanski <t...@cabanski.com> wrote:
I have a document with an id like "SiteProduct/1/2".  When I do a query like the following, I get Id = "SiteProduct/1/2" as expected:

var doc = from sp in session.Query<SiteProductDocument, Eleanor_SiteProductDocument_Search>()
    where sp.ProductId == productId && sp.SiteId == siteId
    select sp).FirstOrDefault();

//doc.id == "SiteProduct/1/2"

However, when I apply a transformer, the Id returned is all lower case: 

var doc = (from sp in session.Query<SiteProductDocument, Eleanor_SiteProductDocument_Search>()
    .TransformWith<SiteProductDocumentWithDimensionContraintsTransformer, SiteProductDocumentWithDimensionConstraints>()
     where sp.ProductId == productId && sp.SiteId == siteId
     select sp).FirstOrDefault();

//doc.id == "siteproduct/1/2"

Is this the expected behavior?  Looking up a document with the lower case id does work ok so, although it causes some of our tests to fail, it does not seem like a huge problem in the application.  For example:

SiteProductDocumentWithDimensionConstraints siteProduct = (from sp in session.Query<SiteProductDocument, Eleanor_SiteProductDocument_Search>()
       .TransformWith<SiteProductDocumentWithDimensionContraintsTransformer, SiteProductDocumentWithDimensionConstraints>()
        where sp.ProductId == productId && sp.SiteId == siteId
        select sp).FirstOrDefault();

var queryDoc = (from sp in session.Query<SiteProductDocument, Eleanor_SiteProductDocument_Search>()
    where sp.Id == siteProduct.Id
    select sp).FirstOrDefault();

//queryDoc is non-null and is the expected document

var queryDoc = session.Load<SiteProductDocument>(siteProduct.Id);

//queryDoc is non-null and is the expected document

--
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/groups/opt_out.

JBA

irakurri gabe,
2014(e)ko uzt. 28(a) (15:14:40)14/7/28
Hartzailea: rav...@googlegroups.com
I know this is an old thread but I am reviving it because the same problem has been causing me headaches.

Oren, you state that it is "by design" that when using Id from a transformer, we get the lower cased id stored in the index.  

This behaviour seems completely wrong to me, and in fact contradicts your documentation at  http://ravendb.net/docs/2.5/client-api/querying/results-transformation/result-transformers where it is stated that

Main features of the Result Transformers are:
I. Stand-alone, separated from Index.

If I include the an Id property from my entity in the output of a transformation, it should return that property as it is in the entity.  

to take a modification of the example on that documentation page, where I've added an Id property:

public class Order {
public string Id {get;set;}
public DateTime OrderedAt {get;set;}
public Status Status {get;set;}
public string CustomerId {get;set;}
public IList < OrderLine > 
Lines {get;set;}
}

public class OrderStatisticsTransformer: AbstractTransformerCreationTask < Order > {
public OrderStatisticsTransformer() {
TransformResults = orders => from order in orders
select new {
order.Id,
order.OrderedAt,
order.Status,
order.CustomerId,
CustomerName = LoadDocument < Customer > (order.CustomerId).Name,
LinesCount = order.Lines.Count
};
}
}

the TransformResults function is explicitly referencing order.Id, which is a string property of the order object and not necessarily lowercase.  It is extremely confusing for the transformer to return the lowercase __document_id value from the index.  It simply is not what was asked for or referenced in the code.  

Does order.CustomerId return lowercase? If so, is this true equally whether or not CustomerId is indexed?    If the answer depends on whether or not it is indexed, then it seems wrong that the output of the transfomer should be dependent on whether or not the field is indexed and could be modified by changing the index, and again is contrary to the statement that it is "stand-alone,separated from Index.".  If the answer is that it returns CustomerId in its original casing, regardless of whether or not it is indexed, then it seems wrong that there is different behaviour only for properties that happen to be named "Id". 

Either way, I think the lowercase index values should be reserved for comparison during searching and not used for transformer output.  

Oren Eini (Ayende Rahien)

irakurri gabe,
2014(e)ko uzt. 30(a) (03:02:21)14/7/30
Hartzailea: ravendb
Transformer has nothing to do with indexes, correct. But they do operate on the objects given to them.
During indexing, we provide the transformer with an object that contains the stored fields for the index, which will fall back to the index if the value isn't stored.

Note the distinction between stored & indexed here.
However, the document id is _always_ stored, and it is always stored as lower case.

We don't want to load the results from disk, because that would be more expensive. You can work around this by explicitly asking for the id from the document using:

MetadataFor(item)["@id"]

IIRC.



Oren Eini

CEO


Mobile: + 972-52-548-6969

Office:  + 972-4-622-7811

Fax:      + 972-153-4622-7811





For more options, visit https://groups.google.com/d/optout.

michael...@fewzion.com

irakurri gabe,
2014(e)ko abu. 30(a) (13:48:43)14/8/30
Hartzailea: rav...@googlegroups.com
Hi Oren,

This behavior is causing problems for us also.

I have tried the suggested work around below, however this is just returning null.

TransformResults = docs => from doc in docs
                                       select new
                                       {
                                           Id = MetadataFor(doc)["@id"]
                                       };

Note. I tried changing @id to @etag just to experiment and this is working fine.

Many thanks,
Michael

Oren Eini (Ayende Rahien)

irakurri gabe,
2014(e)ko abu. 30(a) (16:25:56)14/8/30
Hartzailea: ravendb
Try this, then:

TransformResults = docs => from doc in docs
                                       select new
                                       {
                                           Id = AsDocument(doc)["__document_id"]
                                       };

michael...@fewzion.com

irakurri gabe,
2014(e)ko abu. 31(a) (09:04:51)14/8/31
Hartzailea: rav...@googlegroups.com
Hi Oren,

Thanks for your quick response.

I gave this a try, it is now returning an id, but it is still in lower case. One thing I forgot to mention is that we are using our own Id strategy and we are setting the Id property ourselves before calling session.Store.

Also, we have a work around in place now, as we were able to construct the Id in the transformer from other properties of the document, so this issue is lower priority for us now, however would still be good to find a more generic work around for the future.

Many thanks,
Michael

Oren Eini (Ayende Rahien)

irakurri gabe,
2014(e)ko abu. 31(a) (09:06:24)14/8/31
Hartzailea: ravendb
If you want an id from a transformer, it is always going to be lower case.

Jeremy Holt

irakurri gabe,
2014(e)ko ira. 3(a) (17:27:20)14/9/3
Hartzailea: rav...@googlegroups.com
I also keep getting bitten by this.

Would it not be possible for a query to simply recognize StringToLower() - this would then make the problem disappear.

Jeremy

Oren Eini (Ayende Rahien)

irakurri gabe,
2014(e)ko ira. 4(a) (02:28:08)14/9/4
Hartzailea: ravendb
I'm not sure that I'm following.

Jeremy Holt

irakurri gabe,
2014(e)ko ira. 14(a) (18:36:06)14/9/14
Hartzailea: rav...@googlegroups.com
If I write a query:

var query = _session.Query<MyDoc>().Where(c=>c.Id.ToLower() = myParam.ToLower())

I get an error message saying that RavenDb can not understand "Id.ToLower()".

If Raven could understand ToLower(), then even though its a bit of a hack, I would get around the upper/lower case issue after running the query through a transformer. It's not really a big deal, since my tests spot this problem almost immediately - but I still spend 5 minutes scratching my head each time trying to understand why my tests fail :)

Oren Eini (Ayende Rahien)

irakurri gabe,
2014(e)ko ira. 15(a) (01:18:05)14/9/15
Hartzailea: ravendb
Why do you want to do that?
Queries are already case sensitive.



Oren Eini

CEO


Mobile: + 972-52-548-6969

Office:  + 972-4-622-7811

Fax:      + 972-153-4622-7811




Jeremy Holt

irakurri gabe,
2014(e)ko ira. 16(a) (01:47:16)14/9/16
Hartzailea: rav...@googlegroups.com
Precisely!

Say the documentId is SpareParts-100. After running through the transformer it returns as spareparts-100.

If I forget that the transformer has made it lower case then I would write 

session.Query<SparePart>.Where(c=>c.Id=="SpareParts-100") which of course doesn't give my what I'm looking for.

If I could just write 
session.Query<SparePart>.Where(c=>c.Id.ToLowerCase() == "spareparts-100") I would spend a but less time scratching my head. 

Oren Eini (Ayende Rahien)

irakurri gabe,
2014(e)ko ira. 16(a) (01:49:27)14/9/16
Hartzailea: ravendb
This works!

session.Query<SparePart>.Where(c=>c.Id=="SpareParts-100") 

Oren Eini

CEO


Mobile: + 972-52-548-6969

Office:  + 972-4-622-7811

Fax:      + 972-153-4622-7811



Erantzun guztiei
Erantzun egileari
Birbidali
0 mezu berri