Индекс RethinkDB для filter + orderby

Допустим, таблица comments имеет следующую структуру:

id | author | timestamp | body

Я хочу использовать индекс для эффективного выполнения следующего запроса:

r.table('comments').getAll("me", {index: "author"}).orderBy('timestamp').run(conn, callback)

Есть ли другой эффективный метод, который я могу использовать?

Похоже, что в настоящее время индекс не поддерживается для отфильтрованного результата таблицы. При создании индекса для timestamp и добавлении его в качестве подсказки в orderBy('timestamp', {index: timestamp}) я получаю следующую ошибку:

RqlRuntimeError: Индексированный order_by может выполняться только для TABLE. в:


person Robert Zaremba    schedule 02.11.2013    source источник


Ответы (4)


Это можно сделать с помощью составного индекса в полях «автор» и «отметка времени». Вы можете создать такой индекс следующим образом:

r.table("comments").index_create("author_timestamp", lambda x: [x["author"], x["timestamp"]])

Затем вы можете использовать его для выполнения запроса следующим образом:

r.table("comments")
 .between(["me", r.minval], ["me", r.maxval]
 .order_by(index="author_timestamp)

Между работами, как это сделал get_all в вашем исходном запросе, потому что он получает только документы, у которых есть автор «я» и любая временная метка. Затем мы делаем order_by для того же индекса, который упорядочивает по метке времени (поскольку все ключи имеют одного и того же автора). Суть здесь в том, что вы можете использовать только один индекс для доступа к таблице, поэтому нам нужно втиснуть всю эту информацию в тот же индекс.

person Joe Doliner    schedule 03.11.2013
comment
Возможно ли это сделать с несколькими авторами? т. е. вы хотите получить 10 последних комментариев автора John или Jane. - person Chris Talman; 27.04.2018

В настоящее время невозможно связать getAll с orderBy, дважды используя индексы. Заказ с индексом сейчас можно сделать только на столе.

NB: команда orderBy с индексом orderBy({index: 'timestamp'}) (не нужно повторять ключ)

person neumino    schedule 03.11.2013

Был выбран ответ Джо Долинера, но мне он кажется неправильным.

Во-первых, в команде between не был указан индексатор. Поэтому between будет использовать первичный индекс.

Во-вторых, between возвращает выбор

table.between(lowerKey, upperKey[, {index: 'id', leftBound: 'closed', rightBound: 'open'}]) → selection

и orderBy не может работать при выборе с индексом, только таблица может использовать индекс.

table.orderBy([key1...], {index: index_name}) → selection<stream>
selection.orderBy(key1, [key2...]) → selection<array>
sequence.orderBy(key1, [key2...]) → array
person kureikain    schedule 13.08.2015

Вы хотите создать так называемый «составной индекс». После этого вы можете запросить его эффективно.

//create compound index
r.table('comments')
.indexCreate(
  'author__timestamp', [r.row("author"), r.row("timestamp")]
)

//the query
r.table('comments')
.between(
  ['me', r.minval],
  ['me', r.maxval],
  {index: 'author__timestamp'}
)
.orderBy({index: r.desc('author__timestamp')})  //or "r.asc"
.skip(0)     //pagi
.limit(10)   //nation!

Мне нравится использовать два символа подчеркивания для составных индексов. Это просто стилистически. Неважно, как вы решите назвать свой составной индекс.

Ссылка: Как использовать getall с orderby в RethinkDB

person wle8300    schedule 13.09.2016