Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a RavenDB index that returns a list of strings?

I have a collection of documents "WineDocument" on the form:

{
  "Name": "Barbicato Morellino Di Scansano",
  "Country": "Italy",
  "Region": "Tuscany",
}

I need to make a query to find all unique values of the "Country" field. I have been trying to create an index looking something like:

class WineCountriesIndex: AbstractIndexCreationTask<WineDocument, string> {
        public BeverageCountriesIndex() {
            Map = wines => from wine in wines
                           where wine.Country != null
                           select new { Key = wine.Country };
            Reduce = results => from result in results
                                group result by result into g
                                select new { Key = g.Key };
        }
    }

The index gets created ok and I try to use it with the following code:

IList<string> countries = session.Query<string, WineCountriesIndex>().ToList();

But this gives an JsonSerializationException: "Cannot deserialize JSON object into type 'System.String'.". I guess it is because the Json parser cannot parse { Key = "Italy } to a string. But I don't know how to make a map/reduce return just a string.

like image 282
David Nordvall Avatar asked Dec 09 '11 22:12

David Nordvall


2 Answers

I don't know if this is the best way to go about it but this is how I solved it. I created an index looking like:

class WineCountriesIndex: AbstractIndexCreationTask<WineDocument, WineCountriesIndex.Result> {
    public class Result {
        public string Country { get; set; }
    }

    public WineCountriesIndex() {
        Map = wines => from wine in wines
                       where wine.Country != null
                       select new { Country = wine.Country };
        Reduce = results => from result in results
                            group result by result.Country into g
                            select new { Country = g.Key };
    }
}

Then I use this code to make the actual query:

using(IDocumentSession session = _store.OpenSession()) {
    return session.Query<WineCountriesIndex.Result, WineCountriesIndex>().Select(country => country.Country).ToList();
}
like image 130
David Nordvall Avatar answered Nov 02 '22 23:11

David Nordvall


The problem is that your index isn't outputting a string, it is outputing an object with a Key property that is a string. You do do a projection, if you really want, but I think that David answers is better.

like image 25
Ayende Rahien Avatar answered Nov 02 '22 23:11

Ayende Rahien