Data Model

Aurinko uses two components for storing data:

  1. MongoDB for persistent data
  2. Solr as backend for search and for serving the web site

Listing

A listing represents a telephone book entry.

Durable listing model

{
    "id": "383", // the id generated by the old system
    "site": "opendi.at", // the site id, usually the domain
    "title": "Dipl.-Ing.", // the title of the person (optional)
    "name": "Wolfgang", // the given name of a person (optional)
    "surname": "Grafl", // the name of a person or company
    "street": "Ferdinand-Porsche-Ring 7", // the full street as formatted in the country
    "zip": "2700", // the zip code of the city
    "place": "Wiener Neustadt", // the city name
    "cc": "at", // the country code
    "contacts": [  // list of contacts
        {
            "type": "telephone", // type of the contact
            "visible": true, // the contact is shown if visible = 1
            "val": "+43262225237" // the value of this contact
        },
        {
            "type": "fax",
            "visible": true,
            "val": "+43262225237"
        }
    ],
    "updated": null, // timestamp, when this listing was last updated
    "created": "2011-09-26 13:01:41", // timestamp when this listing was created,
    "sources" : [
        { "name" : "opendi", "id" : "100012030" },
        { "name" : "opendi", "id" : "5533232" }
    ],
    "parent_id": "" // parent id (which is an opendi id)
}

Currently the following contact types are supported:

Type Description
telephone e.164 formatted phonenumber
fax e.164 formatted faxnumber
cell e.164 formatted phonenumber
email email (like: cg@opendi.com)
pager pager id (pager IDs are not following a specific format)

Note: Companies most likely fill only the “Name”field, but not the “Given Name”field. This isn’t reliable to determine if

Search listing model

The search listing model is very similar at first look:

{
    "id": "383",
    "site": "opendi.at",
    "title": "Dipl.-Ing.",
    "name": "Wolfgang",
    "surname": "von Grafl",
    "surname_slug": "von-grafl",
    "street": "Ferdinand-Porsche-Ring 7",
    "zip": "2700",
    "place": "Wiener Neustadt",
    "place_slug": "wiener-neustadt",
    "cc": "at",
    "place_values": [
        "Oberösterreich",
        "Wiener Neustadt",
        "2799"
        "Altwien"
        "wiener-neustadt",
        "altwien",
        "oberoesterreich"
    ],
    "contacts_values": [
        "+43262225237",
        "+43262225255",
        "cg@grobmeier.de"
    ],
    "parent_id": "",
    "doc": '' // json_encoded durable listing model
}

The differences are:

  • contacts are not stored as objects. While it is possible to store sub documents in Solr, it’s currently not possible to return the full document. For that reason all visible contacts are stored as multivalued strings. This enables to find a document by a specific contact value, regardless it’s type
  • the doc property contains a json encoded version of the durable model
  • the place_values is a flat value containing all search strings relevant to this listing. The property locality contains the locality as shown on the actual postal address
  • place_values are enriched when the data is pushed from Corona or from UA
  • on push, the surname is stored in a slugified version surname_slug
  • on push, the place is stored as slugified version in place_slug
  • on push, all slugified places: states, city-districts, place itself are put into place_values

The design goals for the search listing model is to keep relevant, potential searchable fields as property, but to deliver the document which will be rendered as durable model.

In general, the search model is more or less a flat, redundant version of the durable model, containing the original model itself.

Place

Durable Place Model

{
    "_id" : ObjectId("53d10a008e89bee9633f9679"),
    "name" : "Langau",
    "slug" : "langau",
    "cc" : "AT",
    "country" : "Österreich",
    "administrative" : {
        "state" : {
            "name" : "Niederösterreich",
            "slug" : "niederoesterreich"
        }
    },
    "zip" : [
        "2091",
        "3294"
    ],
    "communities" : [
        {
            "name" : "Hessendorf",
            "zip" : [
                "2091"
            ]
        },
        {
            "name" : "Langau",
            "zip" : [
                "2091"
            ]
        },
        {
            "name" : "Neuhaus-Langau",
            "zip" : [
                "3294"
            ]
        },
        {
            "name" : "Grünau",
            "zip" : [
                "3294"
            ]
        }
    ]
}

Search place model

{
    "cc": "AT",
    "name": "Langau",
    "slug": "langau",
    "country": "Österreich",
    "loc": "47.8460232,15.1284167",
    "state_name": "Niederösterreich",
    "state_slug": "niederoesterreich",
    "state_loc": "48.2817813,15.7632457",
    "zip": [
        "2091",
        "3294"
    ],
    "letter": "l"
}