Raven DB document serialization to JSON bug and a couple JSON insert and retrieve questions

361 views
Skip to first unread message

Jim Baltika

unread,
Apr 12, 2012, 2:14:10 PM4/12/12
to rav...@googlegroups.com
Hey, 

The problem number one:
I need to use a lot of dynamic and IDictionary<stringobjectobject instances (all JSON serializable) in the web app. However, when store them in Raven , raven creates 'crappy' json .
 I don't know how to escape from Raven converting simple like HashSet<Guid> to  "$type": "System.Collections.Generic.HashSet`1[[System.Guid, mscorlib]], "$values": ...  It think this is small bug in the code. Its would be better to fix on raven level (private static bool ShouldSimplfyJsonBasedOnType(string typeValue, JsonProperty jsonProperty) then to have some patch  in my code.

The question number two:
How to insert json to the Raven directly not trough session.Store but rather JSON string formatted accordingly raven db standard?  I think I saw somewhere in samples or Raven Test app , but I can find right now. Can anybody give me a hint?
The question number three?
The remember watching Rob Aston's presentation on youtube and he mention passing complex query from IIS to the raven and getting results not deserialize to some C# object but passing JSON back to the browser user. Can anybody give me a hint?

                    var document = new Dictionary<stringobject>(StringComparer.InvariantCultureIgnoreCase);
                    document["ProductHashSetId"] = new HashSet<Guid> { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
                    document["ProductListId"] = new List<Guid> { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
                    document["ProductArrayId"] = new List<Guid> { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() }.ToArray();
                    document["ProductCollectionId"] = new Collection<Guid> { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
 
                    session.Store(document, "mycollection/1");
                    session.SaveChanges();

OR
                    dynamic document = new ExpandoObject();
                    document.ProductHashSetId = new HashSet<Guid> { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
                    document.ProductListId = new List<Guid> { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
                    document.ProductArrayId = new List<Guid> { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() }.ToArray();
                    document.ProductCollectionId = new Collection<Guid> { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
 
                    session.Store(document, "mycollection/2");
                    session.SaveChanges();

{
  "ProductHashSetId": {
    "$type": "System.Collections.Generic.HashSet`1[[System.Guid, mscorlib]], System.Core",
    "$values": [
      "2d0e489a-2a81-49fd-b98c-0d468aebfaaf",
      "6ce6bd6a-9602-4116-b6e6-6c88163b3369",
      "6cba607c-0d5d-42fb-bdaa-3a75563d96ba"
    ]
  },
  "ProductListId": {
    "$type": "System.Collections.Generic.List`1[[System.Guid, mscorlib]], mscorlib",
    "$values": [
      "12d876ff-3d98-478b-9351-6e130245ed07",
      "963594de-16fe-4c78-95d6-1a13cfa9f655",
      "ce0a681d-f290-4cbc-b7fa-e6ca630f8540"
    ]
  },
  "ProductArrayId": {
    "$type": "System.Guid[], mscorlib",
    "$values": [
      "b3d0c0ca-6bf2-42a8-9b1d-4b9f79d6f40e",
      "6936bdce-7302-431b-9cf5-1f9828db4f61",
      "2d265054-6d81-4843-b3c9-20487908af7d"
    ]
  },
  "ProductCollectionId": {
    "$type": "System.Collections.ObjectModel.Collection`1[[System.Guid, mscorlib]], mscorlib",
    "$values": [
      "2092b56a-7e8a-484e-b132-590e741b2a94",
      "95982c2c-7e33-45d2-916e-2d63ff8315a6",
      "943376d7-63b7-4745-9b0a-bf5262729ea5"
    ]
  }
}

Should be something like that:
{
  "ProductHashSetId": [
    "2d0e489a-2a81-49fd-b98c-0d468aebfaaf",
    "6ce6bd6a-9602-4116-b6e6-6c88163b3369",
    "6cba607c-0d5d-42fb-bdaa-3a75563d96ba"
  ],
  "ProductListId": [
    "12d876ff-3d98-478b-9351-6e130245ed07",
    "963594de-16fe-4c78-95d6-1a13cfa9f655",
    "ce0a681d-f290-4cbc-b7fa-e6ca630f8540"
  ],
  "ProductArrayId": [
    "b3d0c0ca-6bf2-42a8-9b1d-4b9f79d6f40e",
    "6936bdce-7302-431b-9cf5-1f9828db4f61",
    "2d265054-6d81-4843-b3c9-20487908af7d"
  ],
  "ProductCollectionId": [
    "2092b56a-7e8a-484e-b132-590e741b2a94",
    "95982c2c-7e33-45d2-916e-2d63ff8315a6",
    "943376d7-63b7-4745-9b0a-bf5262729ea5"
  ]
}

Matt Warren

unread,
Apr 12, 2012, 3:06:09 PM4/12/12
to rav...@googlegroups.com
For 1), I think this is because you're passing in your types as object/dynamic, so it stores the full type info to aid it when deserializing. But I don't know if there's a way to override it or not, maybe TypeNameHandling in Json.net will help.

For 2) you can use code like this:
       store.DatabaseCommands.Put("collectionName", null,
                                        RavenJObject.Parse(contentJson),
                                        RavenJObject.Parse(metadataJson));

Note that if you do this a HTTP call will be issued straight away, so no bulk-upload like .SaveChanges(..) and you need to setup the metadata yourself. If you want batching, see http://ravendb.net/docs/client-api/advanced/databasecommands/batch.

For 3), the .NET client API under the hood just does regular http PUT/GET/POST calls. If you run a C# client app and look in fiddler you can see what's going on. You can then just mimic these network call. There's some docs here http://ravendb.net/docs/http-api and http://ravendb.net/docs/http-api/http-api-indexes-querying

Oren Eini (Ayende Rahien)

unread,
Apr 12, 2012, 3:21:44 PM4/12/12
to rav...@googlegroups.com
Matt answered point 2 & 3.
For the first one, you can set the TypeNameHandling to None, which should remove those.
The problem is that we won't know how to deserialize it back. We don't have info in the document, and we don't have info in the entity, how would we know to give you back a hash set vs. a list?

Jim Baltika

unread,
Apr 12, 2012, 6:31:31 PM4/12/12
to rav...@googlegroups.com
Thanks guys,

I am on right track right now.  Oren, I am unleashing power of  Raven for CMS world for Sitecore to be precise right now. The Sitecore has this "Item' object which is equivalent of  'dynamic/IDictionary<string,object> ' in C# world. I am storing all values in raven and in with ReduceResult classes I exposing  the data and with raven search & boosting it makes even more powerful. 


Reply all
Reply to author
Forward
0 new messages