Hiro Protagonist
Hiro Protagonist

Reputation: 483

RavenDB query returns null

I'm on RavenDB 3.5.35183. I have a type:

import com.mysema.query.annotations.QueryEntity;

@QueryEntity
public class CountryLayerCount
{
    public String countryName;
    public int layerCount;
}

and the following query:

private int getCountryLayerCount(String countryName, IDocumentSession currentSession)
{           
    QCountryLayerCount countryLayerCountSurrogate = QCountryLayerCount.countryLayerCount;
    IRavenQueryable<CountryLayerCount> levelDepthQuery = currentSession.query(CountryLayerCount.class, "CountryLayerCount/ByName").where(countryLayerCountSurrogate.countryName.eq(countryName));
    CountryLayerCount countryLayerCount = new CountryLayerCount();
    try (CloseableIterator<StreamResult<CountryLayerCount>> results = currentSession.advanced().stream(levelDepthQuery))
    {
        while(results.hasNext())
        {
            StreamResult<CountryLayerCount> srclc = results.next();
            System.out.println(srclc.getKey());
            CountryLayerCount clc = srclc.getDocument();
            countryLayerCount = clc;
            break;
        }
    }
    catch(Exception e)
    {
    }
    return countryLayerCount.layerCount;
}

The query executes successfully, and shows the correct ID for the document I'm retrieving (e.g. "CountryLayerCount/123"), but its data members are both null. The where clause also works fine, the country name is used to retrieve individual countries. This is so simple, but I can't see where I've gone wrong. The StreamResult contains the correct key, but getDocument() doesn't work - or, rather, it doesn't contain an object. The collection has string IDs.

In the db logger, I can see the request coming in:

Receive Request #  29: GET     - geodata - http://localhost:8888/databases/geodata/streams/query/CountryLayerCount/ByName?&query=CountryName:Germany
Request #  29: GET     -    22 ms - geodata    - 200 - http://localhost:8888/databases/geodata/streams/query/CountryLayerCount/ByName?&query=CountryName:Germany

which, when plugged into the browser, correctly gives me:

{"Results":[{"countryName":"Germany","layerCount":5,"@metadata":{"Raven-Entity-Name":"CountryLayerCounts","Raven-Clr-Type":"DbUtilityFunctions.CountryLayerCount, DbUtilityFunctions","@id":"CountryLayerCounts/212","Temp-Index-Score":0.0,"Last-Modified":"2018-02-03T09:41:36.3165473Z","Raven-Last-Modified":"2018-02-03T09:41:36.3165473","@etag":"01000000-0000-008B-0000-0000000000D7","SerializedSizeOnDisk":164}}
]}

The index definition:

from country in docs.CountryLayerCounts
select new {
    CountryName = country.countryName
} 

AFAIK, one doesn't have to index all the fields of the object to retrieve it in its entirety, right ? In other words, I just need to index the field(s) to find the object, not all the fields I want to retrieve; at least that was my understanding...

Thanks !

Upvotes: 1

Views: 378

Answers (1)

Marcin
Marcin

Reputation: 1615

The problem is related to incorrect casing.

For example:

try (IDocumentSession sesion = store.openSession()) {
    CountryLayerCount c1 = new CountryLayerCount();
    c1.layerCount = 5;
    c1.countryName = "Germany";

    sesion.store(c1);
    sesion.saveChanges();
}

Is saved as:

{
    "LayerCount": 5,
    "CountryName": "Germany"
}

Please notice we use upper case letters in json for property names (this only applies to 3.X versions).

So in order to make it work, please update json properties names + edit your index:

from country in docs.CountryLayerCounts
select new {
    CountryName = country.CountryName
} 

Btw. If you have per country aggregation, then you can simply query using:

QCountryLayerCount countryLayerCountSurrogate = 
QCountryLayerCount.countryLayerCount;
    CountryLayerCount levelDepthQuery = currentSession
            .query(CountryLayerCount.class, "CountryLayerCount/ByName")
            .where(countryLayerCountSurrogate.countryName.eq(countryName))
            .single();

Upvotes: 2

Related Questions