2
votes

This question regards querying nested dictionaries.

I have a case which can be simplified into the following setup with a style containing a list of SKUs containing a list of Collis.

CLASS DEFINITIONS:

public class Style
{
    public string Name { get; set; }
    public Dictionary<string, Sku> Skus = new Dictionary<string, Sku>();
}
public class Sku
{
    public string Name { get; set; }
    public Dictionary<string, Colli> Collis = new Dictionary<string, Colli>();
}
public class Colli
{
    public string Name { get; set; }
}

JSON DATA IN RAVEN DB:

{
 "Skus": {
    "Sku1": {
      "Collis": {
        "Right": {
          "Name": "Right"
        },
        "Right again": {
          "Name": "Right again"
        },
        "Wrong": {
          "Name": "Wrong"
        }
      },
      "Name": "Sku1"
    },
    "Sku2": {
      "Collis": {
        "Wrong 1": {
          "Name": "Wrong 1"
        },
        "Wrong 2": {
          "Name": "Wrong 2"
        },
        "Wrong 3": {
          "Name": "Wrong 3"
        }
      },
      "Name": "Sku2"
    }
  },
  "Name": "Style1"
}

VALID QUERIES:

(Ask for style with skus of specific names)

var existingStyleWithSku1 = session.Query<Style>().Where(s => s.Skus["Sku1"] != null).ToList();
var nonexistingStyleWithSku4 = session.Query<Style>().Where(s => s.Skus["Sku4"] != null).ToList();

INVALID NESTED QUERY

(Ask for style containing a sku named "Sku1" that contains a colli named "Right")

var styleWithSpecificColli = session.Query<Style>().Where(s => s.Skus["Sku1"].Collis["Right"] != null).ToList();

When i attempt to execute the last query, I get the message:

{ "Url": "/indexes/dynamic/Styles?query=-Skus.get_Item(%2522Sku1%2522).Collis.Right%253A%255B%255BNULL_VALUE%255D%255D%2520AND%2520Skus.get_Item(%2522Sku1%2522).Collis.Right%253A*&start=0&pageSize=128&aggregation=None", "Error": "System.ArgumentException: The field ')CollisRight' is not indexed, cannot query on fields that are not indexed\r\n at Raven.Database.Indexing.Index.IndexQueryOperation.AssertQueryDoesNotContainFieldsThatAreNotIndexes() in c:\Builds\raven\Raven.Database\Indexing\Index.cs:line 628\r\n at Raven.Database.Indexing.Index.IndexQueryOperation.d__1c.MoveNext() in c:\Builds\raven\Raven.Database\Indexing\Index.cs:line 542\r\n at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()\r\n at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()\r\n at System.Collections.Generic.List1.InsertRange(Int32 index, IEnumerable1 collection)\r\n at ........

Is there a way that I can be able to execute the last query? Maybe defining what to index in RavenDB?

Thankyou in advance.

1
I solved the problem. I changed the Skus and Colli collection types from dictionary to native arrays. This way I can use this query: "Skus,Collies,Name:Right". If someone knows how to solve the problem using dictionaries, I would very much like to hear about it :) - Stephan Møller
Stephan, Please post this in the mailing list as a failing test - Ayende Rahien

1 Answers

3
votes

I posted the example above as failing test, but synhershko corrected my code in order to make it work.

It is actually possible to do this. The query just looks like this instead:

WRONG:

var styleWithSpecificColli = session.Query<Style>()
.Where(s => s.Skus["Sku1"].Collis["Right"] != null)
.ToList();

RIGHT:

var styleWithSpecificColli = session.Query<Style>()
 .Select(s => s.Skus["Sku1"])
 .Where(c => c.Collis["Right"] != null)
 .ToList();