Reputation: 606
Is it possible to partial search(like/regex query) on an encrypted field in mongodb?
I have a field which contains encrypted email id. So in mongo the email [email protected]
becomes 1bcuh6762jhjdSOME_ENCRYPTED_VALUE
, now is it possible to do partial search on this encrypted value
Upvotes: 1
Views: 2157
Reputation: 1789
I came across a similar problem i resolved it, by creating hash of all possible values that were more than 3 letters. and created hash for all possible combinations, you can add the value to be set with pre('save')
.
In Schema You can create this function:
function createHash(next) {
this.hashes = hash.createHashForField(this.text);
debug(text);
next();
}
mySchema.pre('save', createHash);
A module for hashing hash.js
const hash = require('crypto');
const adler32 = require('adler32');
const crypto = require('crypto');
const _ = require('lodash');
adler32.register();
module.exports = Hash = {
/**
* This method creates hash of given text;
* @param text - text to hash;
*/
createHash: (text) => {
return crypto.createHash('adler32').update(text, 'ascii').digest('hex');
},
/**
*
* @param text- text separated by spaces
*/
createHashForText: (text) => {
"use strict";
text= text.toLowerCase();
text= text.trim();
let textSlices = _.flatten(text.split(' ').filter(x => x.length)
.map((part) => {
if (part.length < 3) {
return part;
}
let nameSlices = [];
for (let index = 2; index < part.length; index ++) {
let n = part.slice(0, index+1);
textSlices .push(n);
}
return textSlices ;
}));
return textSlices .map(n => Hash.createHash(n));
}
}
after that you can migrate all your records like this:
myModel.find({}).then(docs => {
docs.forEach(doc => doc.save().catch(console.log))
})
Now when search, You will have to use createHash
function to make hash of keyword and search it in your database.
I hope this helps.
Upvotes: 3