Вы можете присоединиться к двум коллекциям в Монго, используя поиск, который предлагается в версии 3.2. В вашем случае запрос будет
db.comments.aggregate({
$lookup:{
from:"users",
localField:"uid",
foreignField:"uid",
as:"users_comments"
}
})
, или вы также можете присоединиться к пользователям, тогда будет небольшое изменение, как указано ниже.
db.users.aggregate({
$lookup:{
from:"comments",
localField:"uid",
foreignField:"uid",
as:"users_comments"
}
})
Он будет работать так же, как левое и правое соединение в SQL.
Ну, так как мы не можем увидеть ваш код, я предложу следующее решение, основанное на моем личном предположении о том, как работает ваш код.
Пожалуйста, имейте в виду, что этот метод не так масштабируем и довольно неэффективен, если у вас есть 100 различных способов создания сеток.
Однако, если у вас есть (например, 3) типа таких способов, например, вы можете использовать константы!
См. Ниже:
public class WebCenterGrid {
//Declare constants with meaningful names for grid creation (add more as you like)
public static final int DEEP_COPY=1, SEARCH=2, REBUILD=3;
public void makeDeepCopy(){
//implementation goes here..
}
public void searchAndPopulate(){
//implementation goes here..
}
public void rebuildGrid(){
//implementation goes here..
}
public void refresh(int operation) {
switch(operation) {
//based on 'operation', call appropriate method!
case DEEP_COPY: this.makeDeepCopy(); break;
case SEARCH: this.searchAndPopulate(); break;
case REBUILD: this.rebuildGrid(); break;
//you can have a default operation for any parameter that is not
//in the list of our defined constants(i.e. the number 143)
default: simpleRefresh(); break;
}
}
}
Итак, что делает вышеприведенное работа решения?
blockquote>Обычно, когда вы вызываете
refresh(int operation)
из одного из ваших других классов, вам нужно передать int в качестве параметра. Это целое число является одной из констант, определенных в самом верху класса. В зависимости от того, какая константа была передана, регистр переключателя будет определять, какой метод вызывать.ПРИМЕР (Допустим, AwesomeGridCreator - это класс, который при вызове refresh () для обновления сетки должен выполнить поиск и затем заполнить сетку (, как вы) упомяните в своем вопросе ).
Назовем целое число (для простоты)
SEARCH_POPULATE
и присваиваем ему ЛЮБОЕ значение , которое мы хотим. Например286
[ 119].Затем мы можем использовать эту константу из любого другого класса, потому что нам не важно, каково ее значение (в данном случае
286
, но какая функциональность она предоставляет при вызовеrefresh()
. [ 1118]public class WebCenterGrid { /*some code here*/ public static final int SEARCH_POPULATE = 286; //integer value doesn't matter public void refresh(int operation) { switch(operation) { case SEARCH_POPULATE: this.searchAndPopulate(); break; } /*...some other code here, we don't care..*/ }
Затем, в классе «призвания»:
public class AwesomeGridCreator{ //some code here WebCenterGrid wcg = new WebCenterGrid(); //The parameter that we pass below (2), will make the refresh() method call //the method that we defined in our switch cases ('searchAndPopulate()'). wcg.refresh(wcg.SEARCH_POPULATE); }
В основном, есть два пути.
Одним из них является использование отражения , это означает: полагаться на информацию о типе среды выполнения , обычно полученную из необработанных строк. Как сказать: у меня есть некоторый объект класса X, и я хочу вызвать метод с именем "doTheFoo ()" для этого объекта.
См. здесь для всех деталей славы.
Несколько лучший способ - использовать класс MethodHandle вместо класса «сырого» метода отражения. См. здесь для ручек.
1110 Но потом: отражение происходит во время выполнения. Ваш код компилируется нормально, но если вы ошибаетесь в деталях, он взрывается во время выполнения.
Таким образом, я предлагаю изучить лямбды, основанные на функции , см. здесь .