Как бы я ни хотел использовать плагин pouchdb-find
, я не мог найти способ добиться того, что мне было нужно. Вместо этого я использовал обходной путь:
Измените структуру документа, чтобы хранить идентификаторы меток в массиве.
{_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']
});
Чтобы запросить записи, которые содержат 'label/3' или 'label/3':
Db.query('records-with-labels', {
keys: [['label/1'], ['label/3']]
});
Это даст нам повторяющиеся записи с обеими метками, но функция сокращения должна помочь их устранить.
Вывод
На данный момент я не знаю, есть ли лучшее решение, но для меня этого достаточно, потому что в моем случае у записи не будет слишком много ярлыков.
Если у вас есть лучшие предложения, прокомментируйте или отредактируйте ответ.
person
Kenny Ki
schedule
06.03.2015