Hibernate Spatial: как определить конверт для большого количества записей

У меня есть следующее:

База данных, содержащая адреса с городом, улицей, номером дома и геометрией.

@Id
@Column(name = "fid", unique = true)
private Integer fid;
@Column(name = "city")
private String city;
@Column(name = "street")
private String street;
@Column(name = "houseNumber")
private String houseNumber;
@javax.persistence.Column(name = "GEOM")
private Geometry geom;

Я хочу, чтобы пользователь вводил (часть) название улицы и/или название города и искал соответствующие адреса (SQL: "SELECT * FROM address WHERE street LIKE '%<streetinput>%' AND city LIKE '%<cityinput>%'").

В конце карта будет увеличена до конверта, содержащего все совпадающие адреса. Немного углубиться в карту.

Поскольку таблица адресов довольно велика (небольшой округ: многие сотни тысяч адресов), очень неэффективно извлекать их все и обрабатывать координаты для определения конверта.

Псевдокод:

envelope = emptyEnvelope;
foreach (address in foundAddresses) {
    envelope.expandToInclude(address.geometry);
}

Это может быть осуществимо для некоторых найденных адресов (до сотен), но нет, если пользователь еще не развернул ни один из них (вся база данных).

Что мне сейчас нужно, так это способ сообщить hibernate пространственному, чтобы он возвращал мне самые минимальные и самые максимальные координаты в пределах возможных объектов.

sql для оракула (только в mysql, postgis и т.п. доступ будет другой):

SELECT 
    MIN(b.GEOM.sdo_point.x) AS minX, MAX(b.GEOM.sdo_point.x) AS maxX,
    MIN(b.GEOM.sdo_point.y) AS minY, MAX(b.GEOM.sdo_point.y) AS maxY
FROM 
    addresses b
WHERE street LIKE ... AND city LIKE ...;

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

Есть ли способ использовать пространственный режим гибернации для запроса конверта с кучей записей? Как это выполняется?


person SirFartALot    schedule 12.03.2019    source источник


Ответы (1)


Прежде всего, Hibernate работает с сущностями. Ваш окончательный запрос не подходит ни к одному объекту, это пользовательские данные. Но вы можете выполнить поиск по этому запросу и получить результат. Я думаю, что ваш окончательный запрос лучше всего подходит для повышения производительности, но если вы хотите использовать гибернативные пространственные запросы, подумайте о доступе к объектам. Вы можете выполнить 4 разных запроса и получить угловые объекты, а затем вручную получить доступ к угловым координатам. Вы можете построить свой запрос в зависимости от этой документации.

person Burak Akyıldız    schedule 14.05.2019
comment
можете ли вы предоставить возможность сбора угловых точек (мин/макс или что-то подобное)? - person SirFartALot; 14.05.2019
comment
Вы можете просто отсортировать запрос текстового поиска с помощью функции byDistance. Дайте fromLatitude и andLongitude в зависимости от угла вашего запроса. Например, для левого верхнего угла вы можете указать fromLatitude(-1 * Double.MAX_VALUE) и andLongitude(Double.MAX_VALUE), затем ограничить результат одним и получить первую строку. Это ближайший объект к левому углу. Сделайте это для 4 угловых концов, получите координаты от этих объектов. - person Burak Akyıldız; 14.05.2019