Пользовательский индексный компаратор в MongoDB
Я работаю с набором данных, состоящим из вероятностных зашифрованных элементов, неотличимых от случайных выборок. Таким образом, последовательные шифрования одного и того же номера приводят к разным зашифрованным текстам. Однако они все еще сравнимы с помощью специальной функции, которая применяет алгоритмы, такие как SHA256, для сравнения двух зашифрованных текстов.
Я хочу добавить список описанных зашифрованных текстов в базу данных MongoDB и проиндексировать ее с использованием древовидной структуры (то есть: AVL). Я не могу просто применить стандартную индексацию базы данных, потому что, как описано, записи должны быть сопоставимы с использованием специальной функции.
Пример: предположим, что у меня есть база данных db и коллекция c, состоящая из следующего типа документа:
{
"_id":ObjectId,
"r":string
}
Кроме того, пусть F (int, string, string) будет следующей функцией:
F(h,l,r) = ( SHA256(l | r) + h ) % 3
где оператор | является стандартной функцией конкатенации.
Я хочу выполнить следующий запрос эффективным способом, например, в коллекции с подходящей индексацией:
db.c.find( { F(h,l,r) :{ $eq: 0 } } )
для h и l выбраны произвольно, но не константы. I.e.: Предположим, что я хочу найти все записи, которые удовлетворяют F (h1, l1, r) для некоторой пары (h1, l1). Позже, в другой момент, я хочу сделать то же самое, но используя (h2, l2) такие, что h1!= H2 и l1!= L2. h и l могут принимать любое значение в наборе целых чисел.
Как я могу это сделать?
Ответы
Ответ 1
Вы можете выполнить этот запрос с помощью оператора $, где, но этот способ не может использовать индекс. Таким образом, для производительности запросов это зависит от размера вашего набора данных.
db.c.find({$where: function() { return F(1, "bb", this.r) == 0; }})
Перед выполнением вышеуказанного кода вам нужно сохранить свою функцию F
на сервере mongodb:
db.system.js.save({
_id: "F",
value: function(h, l, r) {
// the body of function
}
})
Ссылки:
Ответ 2
Я пробовал решение, которое хранит результат функции в вашей коллекции, поэтому я изменил схему, как показано ниже:
{
"_id": ObjectId,
"r": {
"_key": F(H, L, value),
"value": String
}
}
Поле r._key
представляет собой значение F(h,l,r)
с константой h
и l
, а поле r.value
- это исходное поле r
.
Таким образом, вы можете создать индекс в поле r._key
, и ваше условие запроса будет:
db.c.find( { "r._key" : 0 } )