Как получить доступ к объекту Gemfire по уникальному значению или набору значений подобъектов?

У меня ситуация, когда я храню сложный объект в Gemfire. Для простоты это объект клиента, у которого есть несколько атрибутов. Мы также храним Список объектов адресов электронной почты (не только строк электронной почты), адресов, номеров телефонов и ссылок на «чужие системы», которые мне нужны для определения наилучшего способа запроса данных.

Сначала структура объекта (псевдо xsd для простоты)

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="firstName" type="xs:string"/>
      <xs:element name="lastName" type="xs:string"/>
      ...
      <xs:element name="emailAddresses" type="emailAddressType" minOccurs="1"/> <!-- one or more -->
      <xs:element name="foreignSystemIdentifiers" type="foreignSystemIdentifierType"/> <!-- zero or more -->
      ...
    </xs:sequence>
  </xs:complexType>
</xs:element>
<xs:element name="emailAddressType">
    <xs:complexType>
        <xs:element name="emailAddress" type="xs:string"/>
        <xs:element name="addressType" type="xs:string"/>
        ...
    </xs:complexType>
</xs:element>
<xs:element name="foreignSystemIdentifierType">
    <xs:complexType>
        <xs:element name="foreignSystemName" type="xs:string"/>
        <xs:element name="foreignSystemId" type="xs:string"/>
        ...
    </xs:complexType>
</xs:element>
</xs:schema>

Мы храним эти данные в одном регионе как объект Customer по разным причинам, поэтому совместное размещение или аналогичные концепции неприемлемы для нашего варианта использования (хотя это сделало бы это бесконечно проще)

Потребности

  • Доступ к клиенту по уникальному адресу электронной почты (глобально уникальному и подтвержденному перед вставкой)
  • Доступ к клиенту с помощью уникальной комбинации имени и идентификатора внешней системы (снова глобально уникального и проверенного перед вставкой)

При необходимости у нас есть доступ к Elasticsearch, но мы действительно хотели бы решить эти два уникальных запроса на получение, вернув объект клиента напрямую. Как лучше всего решить эту проблему в Gemfire? FWIW, мы также используем Spring-Data-Gemfire.


person fpmoles    schedule 27.01.2015    source источник
comment
Итак, поскольку адрес электронной почты является вложенным объектом, у вас нет доступа первого уровня к строке адреса электронной почты? Я правильно понял?   -  person hubbardr    schedule 27.01.2015
comment
да @hubbardr, вы правы. Такая же ситуация существует для идентификатора внешней системы, с той лишь разницей, что это пара ключ-значение, которую нам нужно запросить на покупку.   -  person fpmoles    schedule 27.01.2015


Ответы (2)


Самый простой случай - использовать запрос (GemFire ​​OQL), чтобы получить то, что вам нужно ...

SELECT c FROM /Customers c, c.emailAddresses e WHERE e.emailAddress = $1

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: я не тестировал запрос, но думаю, что это должно сработать.

Кроме того, адрес электронной почты Sense проверяется и гарантированно является уникальным, вы можете добавить индекс в это поле, чтобы ускорить поиск.

Затем, используя Spring Data GemFire, довольно просто добавить метод Spring Data Repository, например ...

public interface CustomersRepository extends GemfireRepository<Customer, Long> {

  ...

  @Query("SELECT c FROM /Customers c, c.emailAddresses e WHERE e.emailAddress = $1")
  Customer findByEmailAddress(String emailAddrdess);

}

А потом от вас сервисный метод ...

@Service
public class CustomerService {
  ...
  public Customer lookupBy(String emailAddress) {
    ...
    return customerRepo.findByEmailAddress(emailAddress);
  }
}

Надеюсь, это поможет (и ответит на ваш вопрос).

person John Blum    schedule 27.01.2015
comment
Спасибо, Джон, как всегда! - person fpmoles; 28.01.2015
comment
Готово, дайте мне знать, если у вас возникнут проблемы. - person John Blum; 28.01.2015

    @Query("SELECT c FROM /region c, c.emailAddresses email WHERE email.emailAddress = $1")
    List<CustomerEntity> findByEmailAddress(String emailAddress);

Эта часть взрывается трассировкой стека:

Вызвано: java.lang.ClassCastException: com.gemstone.gemfire.cache.query.internal.Undefined не может быть преобразован в com.gemstone.gemfire.cache.query.SelectResults

Что не так с моим запросом?

person Amita Marconda    schedule 12.02.2015