2016-07-04 13 views
10

Pracuję z zestawem danych złożonym z probabilistycznych, zaszyfrowanych elementów, których nie można odróżnić od losowych próbek. W ten sposób sekwencyjne szyfrowanie tego samego numeru skutkuje różnymi szyfrogramami. Jednak są one nadal porównywalne dzięki specjalnej funkcji, która stosuje algorytmy takie jak SHA256 w celu porównania dwóch szyfrogramów.Niestandardowy komparator indeksu w MongoDB

Chcę dodać listę opisanych zaszyfrowanych tekstów do bazy danych MongoDB i zaindeksować ją za pomocą struktury opartej na drzewach (tj .: AVL). Nie mogę po prostu zastosować domyślnego indeksowania bazy danych, ponieważ, jak opisano, rekordy muszą być porównywalne za pomocą specjalnej funkcji.

Przykład: Załóżmy, że mam bazę db oraz kolekcję c złożoną przez następujący Rodzaj dokumentu:

{ 
    "_id":ObjectId, 
    "r":string 
} 

Ponadto niech F (int, string, string) jest następująca funkcja :

F(h,l,r) = (SHA256(l | r) + h) % 3 

gdzie operator | jest standardową funkcją łączenia.

że chce wykonać następujące zapytanie w sposób efektywny, takich jak zbiór z jakiegoś odpowiedniego indeksowania:

db.c.find({ F(h,l,r) :{ $eq: 0 } }) 

H i L wybrany dowolnie, lecz nie stałe. I.e .: Załóżmy, że chcę znaleźć wszystkie rekordy, które spełniają F (h1, l1, r), dla niektórych par (h1, l1). Później, w innym momencie, chcę zrobić to samo, ale używając (h2, l2) takich, że h1! = H2 i l1! = L2. h i l mogą przyjmować dowolną wartość w zbiorze liczb całkowitych.

Jak mogę to zrobić?

+0

świetne pytanie!Czy możesz dodać przykład kodu, aby było bardziej zrozumiałe? – Shawyeok

+0

Wykonano Shawieok. Sprawdź to. –

Odpowiedz

4

Można wykonać to zapytanie użyć operatora $ where, ale w ten sposób nie mogą korzystać z indeksu. Tak więc, dla wydajności zapytań, zależy to od wielkości zbioru danych.

db.c.find({$where: function() { return F(1, "bb", this.r) == 0; }}) 

Przed wykonać powyższy kod, trzeba zapisać funkcję F na serwerze MongoDB:

db.system.js.save({ 
    _id: "F", 
    value: function(h, l, r) { 
     // the body of function 
    } 
}) 

Links:

+0

Uważam, że na razie jest to najlepsza odpowiedź. Nie stworzy to wydajnej struktury indeksu dla mojej bazy danych, ale przynajmniej przeniesie przetwarzanie do DBMS zamiast do aplikacji. –

0

Próbowałem rozwiązanie przechowywania wynik funkcji w swojej kolekcji, więc zmieniłem schemat, jak poniżej:

{ 
    "_id": ObjectId, 
    "r": { 
    "_key": F(H, L, value), 
    "value": String 
    } 
} 

dziedzinie r._key jest wartość F(h,l,r) z stałejh i l, a pole r.value jest oryginalnym polem r. Więc można utworzyć indeks na polu r._key a stan zapytania będą:

db.c.find({ "r._key" : 0 }) 
+0

Tak, rzeczywiście Twoje rozwiązanie działa. Uważam jednak, że moje pytanie nie było wystarczająco jasne. H i L nie są stałymi, ale są wybierane arbitralnie. Np .: Chcę znaleźć wszystkie rekordy, które spełniają F (H1, L1, r), dla niektórych par (H1, L1). Później, w innym momencie, chcę zrobić to samo, ale używając (H2, L2) takiego, że H1! = H2 i L1! = L2. Zaktualizuję pytanie z tym ograniczeniem. –

Powiązane problemy