Многочисленные теги CouchDB
Можно ли использовать несколько меток в CouchDB? У меня есть документы (сообщения) с несколькими тегами. Мне нужно найти сообщения, помеченные произвольным набором тегов. Как мне это сделать? Я мог бы, конечно, сделать это с несколькими вызовами представления, которое дает мне документы для тега, а затем сортирует его в моем приложении, но я хотел знать, есть ли способ достичь такого же результата в области просмотра CouchDB.
Ответы
Ответ 1
В более поздних версиях CouchDB вы можете использовать POST для представления с помощью документа JSON с именем keys
, который позволяет осуществлять поиск с несколькими ключами. Структура будет выглядеть примерно так:
{"keys": ["first_tag", "second_tag", "third_tag"]}
Это может быть POSTED для представления, которое у вас есть, которое испускает теги для соответствующих клавиш.
Этот и другие варианты запросов документируются здесь.
Ответ 2
Я решил эту проблему, создав представление с рекурсивной функцией.
Здесь gist https://gist.github.com/820412
Ответ 3
Я думаю, что следующее должно дать вам немного сложный, но прочный алгоритм, т.е. он быстро находит первые результаты, даже если у вас очень много документов. Вероятно, на практике это будет не очень хорошо: (
Индексировать документы по каждому отдельному тегу и там идентификатор документа:
[<some tag>, <document id>]
например. для документа документов
- docid1 с тегами [синий, зеленый, красный]
- docid2 с тегами [синий, желтый]
вы получаете
['blue', 'docid1']
['blue', 'docid2']
['green', 'docid1']
['red', 'docid1']
['yellow', 'docid2']
Теперь для каждого тега, который вы хотите найти, вы открываете параллельный поиск, начинающийся с [tag,...].
Для каждого тэга вы сохраняете текущую позицию поиска. Если все ваши поисковые запросы совпадают, вы нашли совпадение. Если они не совпадают, попробуйте пропустить по крайней мере самый высокий идентификатор документа с помощью поиска по диапазону. Повторить.
[Это в основном соединение.]
Пропуск теоретически быстрый: у нас есть индекс, чтобы найти эти документы. Практически это, вероятно, медленное из-за всех раундов поездки на сервер. Было бы неплохо разгрузить этот алгоритм функции, выполняемой на сервере. Возможно ли это?
Ответ 4
Один из способов сделать так, как объяснялось выше Райаном Даффилдом. Хотя он решает некоторые из запросов, но с течением времени он станет неуправляемым. Другой способ - использовать полнотекстовый поиск, который в настоящее время не поддерживается CouchDB, но есть внешний плагин с использованием Lucene. здесь http://wiki.apache.org/couchdb/Full_text_search.
Ответ 5
Итак, насколько я понял, ответ НЕТ.
CouchDB не может запрашивать документы, имеющие наличие нескольких тегов (обходной путь с lucene или mysql не учитывается, таким образом мы потеряли некоторые функции CouchDB). Печальные новости: (.
(с наличием нескольких тегов - с A и B, а не с A или B)
UPD!
Это возможно, но с ограничениями только на 2-3 тега.
http://wiki.apache.org/couchdb/EntityRelationship
Запрос несколькими клавишами
Некоторым приложениям необходимо просмотреть пересечение объектов, имеющих несколько ключей. В приведенном выше примере это будет запрос для контактов, которые находятся в группах "Друзья" и "Коллеги". Самый простой способ справиться с этой ситуацией - запросить один из ключей, а затем отфильтровать остальные ключи на стороне клиента. Если частоты клавиш сильно различаются, также может быть полезно сделать начальный вызов для определения ключа с самой низкой частотой и использовать его для извлечения исходного списка документов из базы данных.
Если это не очень хороший вариант, можно индексировать комбинации ключей, хотя рост индекса для данного документа будет экспоненциальным с количеством его ключей. Тем не менее, для малогабаритных наборов клавиш это опция, поскольку ключи можно упорядочить, а ключи, которые являются префиксами более крупного ключа, могут быть опущены. Например, для набора ключей [1 2 3] возможные комбинации клавиш: [1] [2] [3] [1 2] [1 3] [2 3] [1 2 3] Однако индекс должен содержать только клавиши [3] [1 3] [2 3] [1 2 3], поскольку (например) документы, соответствующие клавишам [1 2], могут быть получены с запросом для startkey = [1,2, null] и endkey = [1,2, {}] Число записей индекса будет 2 ^ (n-1) количество ключей.
Последний вариант - использовать отдельный индекс, например couchdb-lucene, чтобы помочь с такими запросами.
Ответ 6
На самом деле тегирование является очень реляционной проблемой и не очень хорошо работает с дизайном CouchDB. Поэтому я решил иметь одну небольшую базу данных для тегов на mysql и иметь фактические документы, хранящиеся в CouchDB. Это позволяет мне получить лучшее из обоих миров. Хотя этот метод имеет проблемы, связанные с синхронизацией, поиск по тегам является эффективной операцией на sql, и контент не слишком беспокоится о репликации или осколке. Спасибо за все ваши ответы.