Text Search

Общая концепция текстового поиска мест

Механизм Text Search в рамках Google Maps JavaScript API используется для поиска географических объектов по произвольному текстовому запросу. В отличие от структурированных запросов (категории, типы мест, координатные фильтры), текстовый поиск анализирует строку запроса как естественный язык и сопоставляет её с базой мест, адресов и организаций.

В основе работы лежит сервис Places Library платформы Google Maps Platform, который объединяет данные о миллионах объектов: ресторанах, отелях, достопримечательностях, учреждениях и географических точках.

Text Search применяется в сценариях, где пользователь вводит свободную форму запроса: «кафе рядом», «музей современного искусства», «аптека открыта сейчас», «hotel in Berlin near center».


Text Search работает поверх Places Service и взаимодействует с серверной инфраструктурой Google Maps Platform. Основные этапы обработки запроса:

  • нормализация строки запроса
  • извлечение семантических сущностей (тип места, бренд, география)
  • сопоставление с индексом Places
  • ранжирование результатов по релевантности
  • фильтрация по доступности данных и ограничениям API

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


Подключение Places Library

Text Search недоступен напрямую в базовом объекте карты и требует подключения библиотеки places.

<script
  src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">
</script>

После загрузки становится доступен конструктор google.maps.places.PlacesService.


const map = new google.maps.Map(document.getElementById("map"), {
  center: { lat: 51.5074, lng: -0.1278 },
  zoom: 13,
});

const service = new google.maps.places.PlacesService(map);

const request = {
  query: "coffee shop",
  fields: ["name", "geometry", "formatted_address", "rating"]
};

service.textSearch(request, (results, status) => {
  if (status === google.maps.places.PlacesServiceStatus.OK) {
    results.forEach(place => {
      console.log(place.name, place.geometry.location.toString());
    });
  }
});

Объект запроса может содержать следующие параметры:

  • query — текстовый поисковый запрос
  • location — центр области поиска (LatLng)
  • radius — радиус поиска в метрах
  • type — фильтрация по типу места
  • region — региональная привязка (например, “us”, “kz”)
  • pageToken — токен для постраничной навигации

Пример расширенного запроса:

const request = {
  query: "restaurant sushi",
  location: new google.maps.LatLng(34.0522, -118.2437),
  radius: 3000,
  type: "restaurant"
};

Ранжирование и релевантность результатов

Результаты Text Search формируются на основе нескольких факторов:

  • соответствие тексту запроса (лексическое совпадение)
  • популярность места (количество отзывов, рейтинг)
  • географическая близость к указанной точке
  • полнота профиля места
  • исторические пользовательские данные (агрегированные сигналы)

Алгоритм не является строго детерминированным и может изменяться без изменения API-интерфейса.


Формат объекта PlaceResult

Каждый результат поиска содержит структуру PlaceResult:

  • name — название объекта
  • formatted_address — полный адрес
  • geometry.location — координаты
  • place_id — уникальный идентификатор места
  • rating — средний рейтинг
  • types — массив типов (restaurant, store, etc.)
  • opening_hours — информация о расписании
  • photos — ссылки на изображения

Пример обработки:

service.textSearch(request, (results) => {
  results.forEach(place => {
    const position = place.geometry.location;

    new google.maps.Marker({
      map,
      position,
      title: place.name,
    });
  });
});

Ограничения и квоты

Text Search подчиняется ограничениям платформы:

  • лимиты запросов в секунду зависят от тарифа
  • обязательное использование API key
  • биллинг за каждый запрос к Places Service
  • ограничение на количество результатов на страницу (обычно до 20)

Пагинация осуществляется через next_page_token, который становится активным с задержкой.


Постраничная загрузка результатов

let service = new google.maps.places.PlacesService(map);

function search(pageToken = null) {
  const request = {
    query: "museum",
    pageToken: pageToken
  };

  service.textSearch(request, (results, status, pagination) => {
    if (status === google.maps.places.PlacesServiceStatus.OK) {
      results.forEach(r => console.log(r.name));

      if (pagination && pagination.hasNextPage) {
        setTimeout(() => {
          pagination.nextPage();
        }, 2000);
      }
    }
  });
}

Фильтрация по типам мест

Text Search поддерживает ограничение по типам объектов. Типы соответствуют классификации Places API:

  • restaurant
  • cafe
  • lodging
  • museum
  • store
  • hospital

Пример:

const request = {
  query: "pizza",
  type: "restaurant"
};

Географическая привязка поиска

Добавление location и radius существенно изменяет результаты, превращая глобальный поиск в локальный.

const request = {
  query: "bank",
  location: new google.maps.LatLng(48.8566, 2.3522),
  radius: 1000
};

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


Использование Place ID

Каждый результат содержит place_id, который используется для последующих запросов Place Details.

const detailRequest = {
  placeId: place.place_id,
  fields: ["name", "formatted_phone_number", "opening_hours"]
};

service.getDetails(detailRequest, (place, status) => {
  console.log(place.name, place.formatted_phone_number);
});

Работа с ошибками и статусами

Статусы ответа:

  • OK — успешный запрос
  • ZERO_RESULTS — ничего не найдено
  • OVER_QUERY_LIMIT — превышен лимит
  • REQUEST_DENIED — ошибка ключа или доступа
  • INVALID_REQUEST — некорректный запрос

Обработка статуса критична для стабильных приложений:

if (status !== google.maps.places.PlacesServiceStatus.OK) {
  console.error("Ошибка поиска:", status);
  return;
}

Производительность и оптимизация

При работе с Text Search важно учитывать:

  • минимизацию количества запросов
  • кеширование результатов по query
  • ограничение радиуса поиска
  • использование debounce при вводе пользователя
  • повторное использование Place ID вместо повторных поисков

Оптимизация особенно важна при динамических интерфейсах (autocomplete-поиск, карты в реальном времени).


Text Search ориентирован на семантические запросы, тогда как Nearby Search — на географическую близость.

Text Search:

  • принимает строку запроса
  • поддерживает более сложные выражения
  • может работать глобально

Nearby Search:

  • требует координат
  • оптимизирован под «рядом со мной»
  • быстрее в локальных сценариях

Оба метода доступны через Places Service и могут комбинироваться в гибридных интерфейсах.


Практические сценарии применения

Text Search используется в следующих архитектурных моделях:

  • поисковые панели в картографических приложениях
  • подбор объектов по категории и тексту
  • фильтрация POI в туристических сервисах
  • корпоративные каталоги на основе геоданных
  • гео-аналитические панели

Особенно эффективно сочетание Text Search с динамическим обновлением карты и кластеризацией маркеров.