Exception when using projection on DocumentQuery

112 views
Skip to first unread message

Anders Strömberg

unread,
Jan 4, 2018, 7:51:48 AM1/4/18
to RavenDB - 2nd generation document database
I get a NotSupportedException when trying to use a projection on a DocumentQuery, my code looks as follows:

 using( var session = _store.OpenSession( ) ) {
        var documentQuery = session.Advanced.DocumentQuery<Order, OrderByCompanyCountryIndex>( );
        documentQuery.WhereEquals( "Country", "Sweden" );

        var queryable = documentQuery.AsQueryable( );

        var result = queryable
          .Select( o => new {
            Order = o,
            Company = RavenQuery.Load<Company>( o.CompanyId )
          } ).ToList( );
}


Is this the expected result?

BR
Anders

Oren Eini (Ayende Rahien)

unread,
Jan 4, 2018, 8:28:43 AM1/4/18
to ravendb
You cannot use `   Company = RavenQuery.Load<Company>( o.CompanyId )` in DocumentQuery, only in linq queries.

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

Anders Strömberg

unread,
Jan 4, 2018, 8:41:53 AM1/4/18
to RavenDB - 2nd generation document database
You could do this with transformers, is there any plans on adding this feature back?

BR
Anders
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.

Oren Eini (Ayende Rahien)

unread,
Jan 4, 2018, 9:13:21 AM1/4/18
to ravendb
You can still do that, just not with DocumentQuery, you can do that if you don't use:


        var queryable = documentQuery.AsQueryable( );

Note that the AsQueryable is bad, because you are still evaluating this on the client side, this will work

 var documentQuery = session.Query<Order, OrderByCompanyCountryIndex>()
        .Where(x=>x.Count == "Sweden")

          .Select( o => new {
            Order = o,
            Company = RavenQuery.Load<Company>( o.CompanyId )
          } ).ToList( );
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

Anders Strömberg

unread,
Jan 5, 2018, 1:02:06 AM1/5/18
to RavenDB - 2nd generation document database
I understand.

I'm currently trying to port our existing application to use Raven 4.0. In this application the user can retrieve data from the database by specifying a number of search criteria that we then use to build a query through DocumentQuery. It was my understanding that this was the purpose of DoucmentQuery, allowing for creating advanced queries on the fly. In 2.5 and forward to 3.5 you could apply transformers to the result of DocumentQuery as well as transformers could do groupings of the result data, both these features seems to be gone now if I understand the forum correctly.

Grouping of data can be done locally with out much loss of performance for us but what is the suggested way forward if you want to do server side projections on queries that are generated on the fly?

BR
Anders 

Oren Eini (Ayende Rahien)

unread,
Jan 5, 2018, 2:25:29 AM1/5/18
to ravendb
You can do that in DocumentQuery, but it is a bit uglier, you do:

        return asyncDocumentQuery.SelectFields<T>(new QueryData(new[] { "{ Order: o, Company: load(o.Company) } " }, Array.Empty<string>(), "o", _null , null, true));
         
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

Anders Strömberg

unread,
Jan 5, 2018, 3:01:26 AM1/5/18
to RavenDB - 2nd generation document database
Ok, I will investigate if I can manage to wrap my head around this.

Thanks for the quick replies as always.

BR
Anders

Anders Strömberg

unread,
Jan 10, 2018, 8:45:44 AM1/10/18
to RavenDB - 2nd generation document database
Ok, So I gave this a try, your example will throw an Index out of bounds exception, the culprit is
var projection = Projections?[i];
in FieldsToFetchToken.cs, maybe this row should be moved to after the check if it is a IsCustomFunction.

However a simple workaround was passing in new [] { string.Empty } for the projections argument.

The problem is that I want to stream the result which does not work with include so I guess I'm stuck. I will try to solve this with using linq and a Queryable instead, however will I end up running in to the same problem there if I want to do both loading and projection in a query that is streamed? If not why is that, I though you used DocumentQuery under the hood to build the RQL question that goes over the wire. 

BR
Anders

Oren Eini (Ayende Rahien)

unread,
Jan 10, 2018, 8:48:49 AM1/10/18
to ravendb
Why do you need to include things?
Don't you basically want to stream the following?

from index `OrderByCompanyCountryIndex` as o
where o.Country == $country
load o.CompanyId as c
select {
  Order: o,
  Company = c
}
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

Anders Strömberg

unread,
Jan 10, 2018, 9:12:06 AM1/10/18
to RavenDB - 2nd generation document database
The reality of what I'm doing is more like this Gist

However the ProcessStep class has a lot more fields, we allow the user to specify some search criteria through a web interface and then build question using DocumentQuery, as the resulting search can be quite large we stream the result but we also need the StepExecutions to be included for each resulting document.

BR
Anders

Oren Eini (Ayende Rahien)

unread,
Jan 10, 2018, 1:39:44 PM1/10/18
to ravendb
Correct me if I'm wrong, but you are always returning the exact same output, right? Regardless of the search criteria?
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

Anders Strömberg

unread,
Jan 11, 2018, 1:17:00 AM1/11/18
to RavenDB - 2nd generation document database
If by exact same out you mean the documents matching the search criteria and their related StepExecutions documents then yes.

av...@ayende.com

unread,
Jan 11, 2018, 11:06:12 AM1/11/18
to RavenDB - 2nd generation document database
Hi Anders,

You can write the DocumetQuery this way:

var documentQuery = session.Advanced
                        .DocumentQuery<Order>("OrderByCompanyCountryIndex")
                        .WhereEquals(x => x.Country, "Sweden")
                        .SelectFields<OrderResult>(new QueryData(
                            new []{"{ Order : o, Company : load(o.CompanyId) }"}, 
                            new List<string>(){"Order", "Company"},
                            "o",
                            null,
                            null,
                            true))
                        .ToList();

Where `OrderResult` is:

class OrderResult
{
public Order Order { get; set; }
public Company Company { get; set; }
}

Also, once http://issues.hibernatingrhinos.com/issue/RavenDB-10144 is fixed, you'll be able to pass this QueryData instead :

new QueryData(
new []{"{ Order : o, Company : load(o.Company) }"}, 
Array.Empty<string>(), 
new QueryData.CustomFunction
{
FromAlias = "o"
});

Best Regards

Oren Eini (Ayende Rahien)

unread,
Jan 11, 2018, 5:06:13 PM1/11/18
to ravendb
Correction, in the next nightly, you'll be able to write it as:

 var docQuery = session.Advanced

     .DocumentQuery<Order>("OrderByCompanyCountryIndex")
     .WhereEquals(x => x.ShipTo.Country, "Sweden")
     .SelectFields<OrderResult>(QueryData.CustomFunction(
         alias: "o",
         func: "{ Order : o, Company : load(o.Company) }")
     );                  
 
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

Anders Strömberg

unread,
Jan 12, 2018, 1:12:26 AM1/12/18
to RavenDB - 2nd generation document database
Hi,

Thanks, this is similar to what Oren suggested earlier but with a non-empty list of projections (When reading the code I understood it as that it does not matter whats stated in the projections list as long as there are equal many entries or more than selected "fields").

The continuation of the problem was that I wanted to stream the result and that does not work.

BR
Anders

Anders Strömberg

unread,
Jan 12, 2018, 1:13:41 AM1/12/18
to RavenDB - 2nd generation document database
Muck nicer interface but I'm guessing it still will not allow for streaming the results?

Oren Eini (Ayende Rahien)

unread,
Jan 12, 2018, 1:19:16 AM1/12/18
to ravendb
This _will_ allow streaming of the results, yes. 
Note that there isn't an include there, so that is fine
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

Anders Strömberg

unread,
Jan 12, 2018, 2:50:22 AM1/12/18
to RavenDB - 2nd generation document database
Reply all
Reply to author
Forward
0 new messages