1

我正在使用 Ydn-Db-Fulltext 允许用户在 HTML5 应用程序中搜索本地联系人数据库。到目前为止,在搜索人名时,它工作得很好,很聪明,并且可以立即返回结果。

下面是一个包含联系人方法数组的联系人对象示例:

{
   "source": "COMPANY",
   "ownerPin": "12345",
   "name": "brian wilkins",
   "dateUpdated": "2014-03-18T14:41:05.217Z",
   "dateAdded": "2014-03-18T14:41:05.217Z",
   "isFavorite": false,
   "socialId": "54321",
   "id": "1",
   "deleted": false,
   "edited": false,
   "favorite": false,
   "contactMethods": [
    {
     "id": "4321",
     "contactKey": "12321",
     "contactId": "1",
     "value": "brian.wilkins@geemail.com",
     "kind": "email",
     "ownerPin": "12345",
     "isPrimary": false
    },
    {
     "id": "5432",
     "contactKey": "2",
     "contactId": "1",
     "kind": "phone",
     "ownerPin": "12345",
     "isPrimary": false
    },
    {
     "id": "23",
     "contactKey": "333",
     "contactId": "1",
     "value": "112345",
     "kind": "extension",
     "ownerPin": "12345",
     "isPrimary": false
    }
   ]
  }

要在“名称”属性上创建索引,我将 fullTextCatalog 设置如下:

fullTextCatalogs: [{
      name: 'name',
      lang: 'en',
      sources: [
        {
          storeName: 'contacts',
          keyPath: 'id',
          weight: 1.0
        }, {
          storeName: 'contacts',
          keyPath: 'name',
          weight: 0.5
        }
      ]
    }],
    stores: [
      {
        name: 'contacts',
        keyPath: 'id',
        autoIncrement: true
      }
    ]
  };
  this.db = new ydn.db.Storage('thedatabase', db_schema);

我可以按名称或 id(键)搜索并获取匹配的联系人列表。似乎很少存储在内存中。每次搜索都会查询本地后备 indexedDB 数据库。

挑战在于我还希望能够基于电子邮件地址和扩展名进行搜索,它们存储在contactMethods 数组中的contactMethods 属性中。“value”属性是我们根据contactMethod类型存储电子邮件地址和/或扩展名的地方。

我尝试将contactMethods 添加为辅助可搜索对象存储,但这导致搜索“Brian”返回两个结果,包括包含姓名的联系人和包含电子邮件地址的contactMethod。理想情况下,我想使用contactId(联系人的外键)并使用它来拉取实际的联系人对象,但这似乎会产生非常昂贵的开销并否定这个伟大的搜索工具的好处。

有没有办法索引不在父级的对象属性?我怎样才能以一种可以扩展且不占用所有资源的方式来解决这个问题?

  this.db.get(entry.storeName, entry.primaryKey).done(function(x) {
    this.textContent += ' [Full name: ' + x.name + ']';  // this is in the contact
    this.textContent += ' [email: ' + x.value + ']';     // but this is in the contactMethod
  }, span);
4

1 回答 1

1

有没有办法索引不在父级的对象属性?

keyPath可以使用点分符号来引用深层对象属性。例如,您可以指定contactMethods.value索引电子邮件,但不幸的是它不适用于数组值 - 在本例中。

因此,显而易见的选择是contactMethods使用父子关系将记录保存在单独的对象存储中。由于 ydn-db 目前不支持embedded模式中的属性,因此在加载父对象时必须加载所有子记录。

或者,IndexedDB v2可能具有由函数表达式生成的虚拟索引。您可以在索引模式中使用 ydn-db generator,例如:

 stores: [
   {
     name: 'contacts',
     keyPath: 'id',
     autoIncrement: true,
     indexes: [{
       name: '$emails',
       multiEntry: true,
       generator: function(record) {
         return record.contactMethods.map(function(x) {return x.value};
       })
     }]
   }
 ]

不过需要注意的一件事是,$emails加载数据时会出现生成的字段。它可能会从记录中删除,以便与 v2 规范匹配。

我们在多个项目中大量使用这个生成器索引,所以我会修复错误。

全文搜索中的索引id和电子邮件地址很方便,但没有意义,因为基于语音的全文搜索将按原样对它们进行索引,而无需规范化。

于 2014-03-23T02:52:43.860 回答