Labs/Weave/Contacts/SchemaV2

From MozillaWiki
< Labs‎ | Weave‎ | Contacts
Jump to: navigation, search

Current (v1) object:

// People object
{
  // guid identifies this person, schema describes the wrapper object
  guid: "af24d-fe488-ab748-b947f",
  schema: "http://labs.mozilla.com/schemas/people/1",

  // we pull out some fields for convenience.
  // we only index fields we pull out.
  displayName: "the foobinator",
  givenName: "foo",
  familyName: "bar",

  documents: {
    default: {
      displayName: "the foobinator",
      name{
        givenName: "foo",
        familyName: "bar"
      },
      emails: [
        {value: "foo@gmail.com", type: "home"},
        {value: "foo@yahoo.com", type: "work"},
        {value: "bar@yahoo.com", type: "other"}
      ]
    }
  },
  documentSchemas: {
    default: "http://portablecontacts.net/draft-spec.html"
  }
}

Suggested changes for v2:

  • The children of documents will be explicitly named with the service that provided the data. This tag name will be exported by the importer that created the record, so it can be used for reverse lookup.
  • Importers are required to coerce to Portable Contacts 1.0 on import.

Pseudocode for producing end-user person record is therefore:

personResult(rawPerson, fields)
{
  ret = {};
  for (aField in fields) {
    for (aDocument in rawPerson.documents) {
      if (aDocument[aField]) {
         mergeDocumentField(ret, aField, aDocument[aField]);
      }
    }
  }
  return ret;
}

Hard/unsolved problems:

  • We should have a model of the cardinality of each field and use it to inform mergeDocumentField. How do we deal with collisions on unique fields?

Proposed (v2) object:

// People object
{
  // guid identifies this person, schema describes the wrapper object
  guid: "af24d-fe488-ab748-b947f",
  schema: "http://labs.mozilla.com/schemas/people/2",

  // we pull out some fields for convenience.
  // we only index fields we pull out.
  displayName: "the foobinator",
  givenName: "foo",
  familyName: "bar",

  documents: {
    servicename1: {
      _refreshDate: "Mar 10, 2010 12:12:12 AM",
      displayName: "foo bar",
      name{
        givenName: "foo",
        familyName: "bar"
      },
      emails: [
        {value: "foo@gmail.com", type: "home"},
        {value: "foo@yahoo.com", type: "work"},
      ]
    },
    servicename2: {
      _refreshDate: "Mar 10, 2010 3:17 PM",
      displayName: "John Bar",
      name{
        givenName: "John",
        familyName: "bar"
      },
      emails: [
        {value: "bar@yahoo.com", type: "other"}
      ],
      location: "Santa Clara, CA"
    },
  }
}


Thoughts about merge hinting:

We will be adding a UI to allow users to merge and split records to handle cases where automatic merge detection fails.

The information that is captured through that user interaction needs to persist so that it can be automatically applied on the next merge.

This is a bit tricky, because it means that we need to capture:

  • In the case of a merge, the field of the source record that should actually be used to indicate equality
  • In the case of a split, the field of the source record that should be ignored.

We posit a mergehints element, as a sibling of documents, like so:

 mergeHints: {
  <service-id>: {
    is_merge_hit: {
      fieldname: "<fieldname>",
      value: "<value>"
    },
    ignore_merge_hit: {
      fieldname: ":<fieldname>",
      value: "<value>"
    }
  }
 }