JSON Mappings with Compass

Upcoming Compass 2.1 M1 will support native JSON indexing (on top of Object, XML, and Resource). This means that using simple mappings, JSON strings can be indexed using Compass API as well as provide search capabilities over them.

As an example, lets take the following simple JSON:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{   
    "id": 1,
    "name": "Mary Lebow",
    "address": {
      "street": "5 Main Street"
      "city": "San Diego, CA",
      "zip": 91912,
    },
    "phoneNumbers": [
      "619 332-3452",
      "664 223-4667"
    ]
  }
}

We can then map using using the following (fully explicit) mappings:

1
2
3
4
5
6
7
8
9
10
11
12
<root-json-object alias="addressbook">
    <json-id name="id" />
    <json-property name="name" />
    <json-object name="address">
        <json-property name="street" />
        <json-property name="city" />
        <json-property name="zip" index="un_tokenized" />
        <json-array name="phoneNumbers" index-name="phoneNumber">
            <json-property />
        </json-array>
    </json-object>
</root-json-object>

Or use the less explicit mapping and let Compass recursively add JSON elements to the index:

1
2
3
<root-json-object alias="addressbook" dynamic="true">
    <json-id name="id" />
</root-json-object>

Once we mapped the JSON elements under a given alias, we can then index it and search on it. Here is an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
JsonObject jsonObject = new DefaultAliasedJSONObject("addressbook", "json string goes here");
// this will index the provided JSON
session.save(jsonObject);
 
// now we can load the Resource that represents it
Resource resource = session.loadResource("addressbook", 1);
resource.getValue("name"); // will get Mary Lebow
 
// we can also get back the JSON content and actual object when using content mapping (see later)
jsonObject = (JsonObject) session.load("addressbook", 1);
 
// Last, we can search
CompassHits hits = session.find("mary");
hits.lenght() // will print one
resource = hits.resource(0);
jsonObject = (JsonObject) hits.data(0);

In terms of JSON object model implementations, Compass comes with a built in one based on json.org. It also integrates with Grails and Jettison implementations of JSON object model. Other object models can be easily implemented as well (any you would like to see?)

That was one of the main features I wanted to add to Compass 2.1, and am happy I manged to get it into Compass 2.1 first milestone release. 2.1 M1 will be released in the upcoming days.

5 Responses to “JSON Mappings with Compass”

  1. Kenny MacLeod Says:

    Upcoming Compass 2.0 M1 will support native JSON indexing

    2.1 M1, shurely….

  2. Shay Banon Says:

    Yep :), I will fix this…

  3. Lukas Vlcek Says:

    This is interesting. It makes me think that Compass could be easily used in similar context like Solr. Users could push new content into index via http. The only thing one has to add would be some simple web server which can accept JSON objects (these will be sent to Compass) and user queries. I am not an expert on Solr but do you see any reason why Compass should not be use in similar manner?

  4. Shay Banon Says:

    Actually no :). I was planning to blog exactly about this. This, with the support for dynamic mappings additions/removal, allows to build a generic Compass server that accepts JSON/XML queries. It would be a really nice addition to Compass, and I am looking for volunteers …

  5. Lukas Vlcek Says:

    Then why don’t you go ahead and blog about this ;-) Or even better, let’s create a new CMP ticket. You probably have some kind of design concept in your head already so let’s write it down. I am really curious about indexing/searching performance of such service.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>