2013-12-16 3 views
1

Я думал, что это было бы просто, когда я его реализовал, однако после долгих поисков, поиска в Google и сканирования документов я не могу найти ответ.Поиск в файле Mongoid hash по ключевому слову

У меня есть поле, которое является хешем, где ключи являются идентификаторами, а значения представляют собой массив других идентификаторов. Например:

{"52ab84929938c7f966d4f116"=>["52ab84919938c7f966d4ee7d"], 
"52ab84929938c7f966d4f117"=>["52ab84919938c7f966d4ee7d"], 
"52ab84929938c7f966d4f0cc"=>["52ab84919938c7f966d4ee7d", "52ab84929938c7f966d4f13d"], 
"52ab84929938c7f966d4f147"=>["52ab84919938c7f966d4ee7d"]} 

Это, вероятно, лучше всего подходит для типа графа дб, но я не знаком с технологией и уже построил остальную часть моего приложения вокруг Mongoid. Это было самое простое решение, которое я мог бы решить для еще одной сложной проблемы.

Итак, мой вопрос заключается в том, как я могу искать записи, которые имеют, скажем, id: 52ab84929938c7f966d4f0cc как ключ в их хэш-поле?

Я пытался делать это стиль массива, как это и есть нулевой результат возвращается:

Course.all_in(:skills_available => sk.id) 

И я знаю, что это не работает, но было бы неплохо, если бы он сделал:

Course.where(:skills_available.key => sk.id) 

ответ

4
Course.where(:'skills_available.52ab84929938c7f966d4f0cc'.ne => nil) 
  • Единственное ограничение в том, что он пропустит: {'52ab84929938c7f966d4f0cc' => nil}
+0

для поиска людей, '.ne' является mongoid' not equal' –

1

Технически Лешек ответил на мой вопрос правильно.

Однако вскоре я понял, что мне нужно найти все документы, в которых этот ключ был в массиве ключей.

Так для справки, вот решение, которое я завелся с помощью:

jt = JobType.first 
jt_skills = "['#{jt.skills_required.join("','")}']" 
m = %Q{ 
    function() { 
    found = false; 
    keys = Object.keys(this.skills_available); 
    keys.forEach(function(key) { 
     if(#{jt_skills}.indexOf(key) > 0) { 
     found = true; 
     } 
    }); 
    if(found) { 
     emit(this._id, keys); 
    } 
    } 
} 
r = %Q{ 
    function(key, values) { } 
} 
courses = Course.where(:skills_available.ne => {}).map_reduce(m,r).out(inline: true) 

Вторая строка преобразует массив в строку, которая может быть передана в функцию JS карты. Функция сопоставления JS проверяет каждый ключ в хэш-значении skills_available, чтобы узнать, находится ли он в массиве skills_required. И если это так, то этот документ включен. Наконец, map_reduce запускается только на курсах, где есть навыки_доступные.

Смежные вопросы