Вопрос

Я использую следующую функцию просмотра для перебора всех элементов в базе данных (чтобы найти тег), но я думаю, что производительность очень низкая, если набор данных большой.Есть какой-нибудь другой подход?

def by_tag(tag):
return  '''
        function(doc) {
            if (doc.tags.length > 0) {
                for (var tag in doc.tags) {
                    if (doc.tags[tag] == "%s") {
                        emit(doc.published, doc)
                    }
                }
            }
        };
        ''' % tag
Это было полезно?

Решение

Отказ от ответственности:Я не тестировал это и не знаю, может ли это работать лучше.

Создайте единый вид химической завивки:

function(doc) {
  for (var tag in doc.tags) {
    emit([tag, doc.published], doc)
  }
};

И запрос с помощью _view/your_view/all?startkey=['your_tag_here']&endkey=['your_tag_here', {}]

Результирующая структура JSON будет немного отличаться, но вы все равно получите сортировку по дате публикации.

Другие советы

Вы можете определить единый постоянный вид, как предлагает Бахадир.однако при выполнении такого рода индексации, не надо выведите документ для каждого ключа.Вместо этого используйте emit([tag, doc.published], null).В текущих версиях выпуска вам пришлось бы выполнять отдельный поиск для каждого документа, но SVN trunk теперь поддерживает указание "include_docs= True" в строке запроса, и CouchDB автоматически объединит документы в ваше представление для вас, без дополнительных затрат пространства.

С этим видом вы на верном пути.Однако вот список мыслей:

Генерация представлений происходит постепенно.Если трафик чтения больше, чем трафика записи, то ваши просмотры вообще не вызовут проблем.Люди, которые обеспокоены этим, как правило, не должны беспокоиться.Исходя из системы отсчета, вам следует беспокоиться, если вы загружаете сотни записей в представление без обновления.

Отправка всего документа замедлит процесс.Вы должны выдавать только то, что необходимо для использования представления.

Не уверен, какой будет производительность val == "%s", но вам не следует переоценивать ситуацию.Если есть массив тегов, вы должны выдавать теги.Конечно, если вы ожидаете, что массив тегов будет содержать не строки, то игнорируйте это.

# Works on CouchDB 0.8.0
from couchdb import Server # http://code.google.com/p/couchdb-python/

byTag = """
function(doc) {
if (doc.type == 'post' && doc.tags) {
    doc.tags.forEach(function(tag) {
        emit(tag, doc);
    });
}
}
"""

def findPostsByTag(self, tag):
    server = Server("http://localhost:1234")
    db = server['my_table']
    return [row for row in db.query(byTag, key = tag)]

Функция byTag map возвращает данные с каждым уникальным тегом в "ключе", затем каждую запись с этим тегом в value, поэтому, когда вы берете key = "mytag", он извлекает все записи с тегом "mytag".

Я протестировал его примерно с 10 записями, и, кажется, на каждый запрос уходит около 0,0025 секунды, не уверен, насколько это эффективно с большими наборами данных..

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top