Запрос GemFire ​​Region по частичному ключу - PullRequest
0 голосов
/ 09 сентября 2018

Когда ключ является составной частью id1, id2 в регионе GemFire ​​и регион разделен с id1, что является лучшим способом получить все строки, ключ которых соответствует id1.

Пара вариантов, о которых мы думаем:

  1. Создать еще один индекс на id1. Если мы это сделаем, мы задаемся вопросом, идет ли это против всех регионов раздела?

  2. Запись данных с учетом функций и фильтрация по (id1, null) для целевой области раздела. Используйте индекс в локальном регионе, используя QueryService?

Подскажите, пожалуйста, есть ли другой способ выполнить запрос с помощью частичного ключа.

1 Ответ

0 голосов
/ 10 сентября 2018

Ну, это может быть реализовано (оптимально) с помощью комбинации # 1 и # 2 в ваших «опциях» выше (в зависимости от того, сохранял ли / ссылался ли ваш объект предметного домена ключ, что было бы в случае использовали SD [G] репозитории.

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

Скажем, ваш "составной" ключ был реализован следующим образом:

class CompositeKey implements PartitionResolver {

  private final Object idOne;
  private final Object idTwo;

  CompositeKey(Object idOne, Object idTwo) {
    // argument validation as necessary
    this.idOne = idOne;
    this.idTwo = idTwo;
  }

  public String getName() {
    return "MyCompositeKeyPartitionResolver";
  }

  public Object getRoutingObject() {
    return idOne;
  }
}

Затем вы можете вызвать функцию, которая запрашивает желаемые результаты, используя ...

Execution execution = FunctionService.onRegion("PartitionRegionName");

При желании вы можете использовать возвращенный Execution для фильтрации только по (сложным) ключам, которые вы хотели запросить (далее уточнять) при вызове функции ...

ComplexKey filter = { .. };

execution.withFilter(Arrays.stream(filter).collect(Collectors.toSet()));

Конечно, это проблематично, если вы не знаете свои ключи заранее.

Тогда вы можете предпочесть использовать ComplexKey для идентификации объекта домена вашего приложения, что необходимо при использовании абстракции / расширения репозитория SD [G]:

@Region("MyPartitionRegion")
class ApplicationDomainObject {

  @Id
  CompositeKey identifier;

  ...
}

И затем вы можете кодировать свою функцию для работы с «локальным набором данных» региона раздела. То есть, когда узел данных в кластере размещает одну и ту же область раздела (PR), он будет работать только с набором данных в «корзине» для этого PR, что достигается следующим образом:

class QueryPartitionRegionFunction implements Function {

  public void execute(FunctionContext<Object> functionContext) {

    RegionFunctionContext regionFunctionContext = 
      (RegionFunctionContext) functionContext;

    Region<ComplexKey, ApplicationDomainObject> localDataSet =
      PartitionRegionHelper.getLocalDataForContext(regionFunctionContext);

    SelectResults<?> resultSet = 
      localDataSet.query(String.format("identifier.idTwo = %s", 
        regionFunctionContext.getArguments);

    // process result set and use ResultSender to send results

  }
}

Конечно, все это гораздо проще сделать с помощью Поддержка аннотаций функций SDG (т.е. в любом случае реализовывать и вызывать вашу функцию).

Обратите внимание, что когда вы вызываете Function, onRegion с использованием GemFire's FunctionService или более удобно с поддержкой аннотаций SDG для выполнения функций, например:

@OnRegion("MyPartitionRegion")
interface MyPartitionRegionFunctions {

    @FunctionId("QueryPartitionRegion")
    <return-type> queryPartitionRegion(..);

}

Тогда ..

Object resultSet = myPartitionRegionFunctions.queryPartitionRegion(..);

Тогда FunctionContext будет RegionFunctionContext (поскольку вы выполнили функцию на PR, которая выполняется на всех узлах в кластере, на котором размещен PR).

Кроме того, вы используете PartitionRegionHelper.getLocalDataForContext (: RegionFunctionContext) для получения локального набора данных PR (т. Е. Сегмента или только фрагмента данных во всем PR (по всем узлам), размещенного этим узлом, который будет основан ваш "кастом" PartitionResolver).

Затем вы можете запросить дополнительную квалификацию или отфильтровать данные по интересам. Вы можете видеть, что я запросил (или уточнил) по idTwo, что не было частью реализации PartitionResolver. Кроме того, это будет требоваться только в предикате запроса (OQL), если вы не указали ключи в своем фильтре с помощью Execution (поскольку, я думаю, это будет учитывать весь «ключ» (idOne & idTwo), основанный на нашем правильно реализованном методе Object.equals() вашего класса ComplexKey.

Но, если вы заранее не знали ключи и / или (особенно если) используете репозитории SD [G], то ComplexKey будет частью вашего домена приложения, который вы могли бы затем Индекс и запрос (как показано выше: identifier.idTwo = ?).

Надеюсь, это поможет!

ПРИМЕЧАНИЕ. Я не проверял ничего из этого, но, надеюсь, он укажет вам правильное направление и / или даст вам дальнейшие идеи.

...