如何查询PouchDB类似于SQL的运营商(How to query PouchDB with SQ

2019-10-22 03:51发布

作为相对较新的PouchDB / CouchDB的,我仍然在试图总结我的周围如何使用地图/减少正确在不同情况下的头。

假定我的文档结构是这样的:

{
  _id: 'record/1',
  labels: {
    // many-to-many relationship
    'label/1': true, // let's assume that this is 'Label A'
    'label/3': true, // 'Label C'
    'label/4': true // 'Label D'
  }
},
{
  _id: 'record/2',
  labels: {
    'label/1': true, // 'Label A'
    'label/2': true // 'Label B'
  }
}

什么是定义视图正确的方式db.query功能搜索:

  1. 与“标签A” “标签B”的记录
  2. 与“标签A” “标签B”记录

Answer 1:

有没有OR在PouchDB / CouchDB的MapReduce的查询操作,所以你必须把它分解成两个单独的查询。

最终,这些类型的操作将在支持pouchdb找到的 ,但截至发稿, $or尚未落实。



Answer 2:

虽然我想用多少pouchdb-find插件,我无法找到一个方法来达到我需要的东西。 相反,我用了一个解决办法:

改变文档结构来存储的ID标签中的阵列

{_id: 'record/1', name: 'Record 1', labels: ['label/1', 'label/2', 'label/3']},
// may not be sorted when being stored
{_id: 'record/2', name: 'Record 2', labels: ['label/1', 'label/5', 'label/7', 'label/3']},
{_id: 'record/3', name: 'Record 3', labels: ['label/2', 'label/3', 'label/4', 'label/5']}

创建一个设计文件

它会散发出多种复杂的按键为每个记录,代表了一个升序排列的所有可能的标签映射。 的map功能将利用递归处理以生成密钥:

{
  _id: '_design/records-with-labels',
  views: {
    'records-with-labels': {
      map: function(doc) {
        // important: sort them so that the required keys to be created are lesser
        var labelIds = doc.labels.sort();
        var lastIx = labelIds.length - 1;

        var emitKey = function emitKey(currentKey, currentIx) {
          console.log('emitting: ' + currentKey.join(',') + ' for ' + doc._id);
          emit(currentKey, null);

          var nextIx = currentIx + 1;

          for (var jumpIx = nextIx + 1; jumpIx <= lastIx; jumpIx++) {
            var jumpedLabelId = labelIds[jumpIx];
            var jumpingKey = currentKey.concat([jumpedLabelId]);

            console.log('emitting: ' + jumpingKey.join(',') + ' for ' + doc._id);
            emit(jumpingKey, null);
          }

          if (nextIx > lastIx) {
            return;
          }

          var nextLabelId = labelIds[nextIx];

          currentKey.push(nextLabelId);

          emitKey(currentKey, currentIx + 1);
        };

        labelIds.forEach(function(labelId, i) {
          emitKey([labelId], i);
        });

      }.toString()
    }
  }
}

例如,该文件record/1将具有产生以下键:

emitting: label/1 for record/1
emitting: label/1,label/3 for record/1
emitting: label/1,label/2 for record/1
emitting: label/1,label/2,label/3 for record/1
emitting: label/2 for record/1
emitting: label/2,label/3 for record/1
emitting: label/3 for record/1

查询

我只需要确保查询标签按升序排序。

若要查询有“标签/ 1” “标签/ 3”记载:

Db.query('records-with-labels', {
  key: ['label/1', 'label/3']
});

若要查询有“标签/ 3” “标签/ 3”记载:

Db.query('records-with-labels', {
  keys: [['label/1'], ['label/3']]
});

这将使我们有两个标签重复记录,但降低的功能将有助于消除它们。

结论

现在我不知道是否有更好的解决方案,但是这是不够好,我因为在我的情况下,记录将不会有太多的标签。

如果您有更好的建议,请评论或编辑答案。



Answer 3:

这是一个较旧的职位。 但是,它可以使用underscore.js帮助一些疑问。 它可以帮助拉出你想要的数据,而无需进行多次前往数据库(除非你想)。



文章来源: How to query PouchDB with SQL-like operators