Я создал базу данных с двумя сгенерированными коллекциями: пользователи и заметки. Каждый содержит ~1 млн документов.
Вот структуры:
Пользователь: (в поле name
используется индекс списка пропуска):
{
"name": "Some user name"
}
Примечание: (поле authors
содержит _key
s к документам из коллекции users
):
{
"title": "Some title",
"authors": [
"12345", "12346", "12347", ...
]
}
Мне нужно присоединиться к коллекции users
в поле authors
, а затем отфильтровать по пользователю name
, но это занимает слишком много времени. Это ~ 3,5 с на моем локальном. Значение Specific name
встречается только один раз.
let specificUsers = (
for user in users
filter user.name == 'Specific name'
return user
)
for note in notes
let authors = (
for user in specificUsers
filter user._key in (note.authors != null ? note.authors : [])
return user
)
filter count(authors) > 0
// filter 'Specific name' in (authors[*].name) // this way takes even longer
limit 10
return merge(note, {
authors: authors
})
Если я опускаю фильтр count
или выполняю фильтрацию по «собственным» атрибутам, он, конечно, загружается быстро. Но на самом деле нужно фильтровать объединенную коллекцию. Как и в реляционных базах данных.
Я делаю что-то не так или в этом случае ArangoDB не должна работать хорошо?
Пожалуйста, дайте мне знать, если мне нужно предоставить более подробную информацию.
@camba1, ты прав. Спасибо. Добавление указателя на авторов[*] действительно помогает. Еще одна вещь, влияющая на производительность, заключается в следующем: (note.authors != null ? note.authors : [])
. Даже с включенным индексом.
Итак, две вещи, которые я пропустил:
authors[*]
.(note.authors != null ? note.authors : [])
. (Думаю, лучше убедиться, что атрибут authors
всегда является массивом)
С самого начала я бы попробовал добавить индекс массива для атрибута автора в коллекции узлов. Найдите значения массива индексации по приведенной ниже ссылке, чтобы узнать, как создать индекс значений массива вместо самого массива. (arangodb.com/docs/3.4/…). В качестве альтернативы вы можете создать пограничную коллекцию между пользователями и заметками и использовать простой обход графа для получения необходимой информации (плюс в этом варианте заключается в том, что вам не нужно фильтровать количество > 0, поскольку заметки без авторов будут естественно отфильтровано)