Пользовательский индексный компаратор в 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 } )