Metin Arama (Yeni)

Platform seçin: Android iOS JavaScript Web Hizmeti
Avrupa Ekonomik Alanı'ndaki (AEA) geliştiriciler

Text Search (New), bir metin sorgusu alır ve eşleşen yerlerin listesini döndürür.

Text Search (New), bir dizeye (ör. "New York'ta pizza", "Ottawa yakınlarındaki ayakkabı mağazaları" veya "123 Main Street") dayalı olarak bir dizi yer hakkında bilgi döndürür. Hizmet, metin dizesiyle ve ayarlanmış konum tercihiyle eşleşen yerlerin listesini döndürür. Text Search (New), yerleri türe göre aramanıza, çalışma saatleri ve puan gibi ölçütleri kullanarak filtrelemenize ve sonuçları belirli bir konumla kısıtlamanıza veya belirli bir konuma yönlendirmenize olanak tanır.

Text Search (New) özelliğini kullanmak için Google Cloud projenizde "Places API (New)" özelliğini etkinleştirmeniz gerekir. Ayrıntılar için Başlangıç bölümüne bakın.

Metin sorgusuyla yer bulma

Metin sorgusundan veya telefon numarasından yer listesi döndürmek için searchByText yöntemini çağırın. Bir istek kullanarak arama parametrelerini belirtin ve ardından searchByText() yöntemini çağırın. Sonuçlar, yer ayrıntılarını alabileceğiniz Place nesnelerinin listesi olarak döndürülür. Aşağıdaki snippet'te, searchByText için bir istek ve çağrı örneği gösterilmektedir:

TypeScript

const request = {
    textQuery: query,
    fields: ['displayName', 'location', 'businessStatus'],
    includedType: '', // Restrict query to a specific type (leave blank for any).
    useStrictTypeFiltering: true,
    locationRestriction: map.getBounds(),
    isOpenNow: true,
    language: 'en-US',
    maxResultCount: 8,
    minRating: 1, // Specify a minimum rating.
    region: 'us',
};

const { places } = await Place.searchByText(request);

JavaScript

const request = {
    textQuery: query,
    fields: ['displayName', 'location', 'businessStatus'],
    includedType: '', // Restrict query to a specific type (leave blank for any).
    useStrictTypeFiltering: true,
    locationRestriction: map.getBounds(),
    isOpenNow: true,
    language: 'en-US',
    maxResultCount: 8,
    minRating: 1, // Specify a minimum rating.
    region: 'us',
};

const { places } = await Place.searchByText(request);
  • textQuery parametresiyle arama yapmak için bir metin sorgusu veya telefon numarası belirtin.
  • Camel case biçiminde bir veya daha fazla veri alanının virgülle ayrılmış listesini belirtmek için fields parametresini (gerekli) kullanın. İstediğiniz alanlar, isteğin fiyatını belirler. Veri alanlarını seçme bölümüne bakın.
  • Yalnızca belirtilen türdeki sonuçları döndürmek için includedType parametresini kullanın.
  • Metin arama sonuçlarınızı belirli bir bölgeye yönlendirmek veya kısıtlamak için locationBias ya da locationRestriction kullanın.
Özelliklerin tam listesini inceleyin.

Sorgu bir telefon numarası içeriyorsa bölge parametresi ayarlanmalıdır. Örneğin, Japonya'da bir yer aramak için telefon numarası kullanıyorsanız ve istekte bulunan alan adı jp ise region parametresini "jp" olarak ayarlamanız gerekir. İstekte region belirtilmezse API, varsayılan olarak ABD ("us") bölgesini kullanır.

Sonuçlar, yer ayrıntılarını alabileceğiniz Place nesnelerinin listesi olarak döndürülür.

Örnek

Aşağıdaki örnekte, sağlanan sorgu metniyle searchByText çağrılır ve ardından sonuçları göstermek için tıklanabilir işaretçiler içeren bir harita doldurulur.

TypeScript

let map: google.maps.Map;
let markers: Record<string, google.maps.marker.AdvancedMarkerElement> = {};
let infoWindow: google.maps.InfoWindow;

async function init() {
    const [{ Map, InfoWindow }, { ControlPosition }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('core'),
    ]);

    const center = { lat: 37.4161493, lng: -122.0812166 };
    map = new Map(document.getElementById('map')!, {
        center,
        zoom: 11,
        mapTypeControl: false,
        mapId: 'DEMO_MAP_ID',
    });

    const textInput = document.getElementById('text-input') as HTMLInputElement;
    const textInputButton = document.getElementById(
        'text-input-button'
    ) as HTMLButtonElement;
    const card = document.getElementById('text-input-card')!;
    map.controls[ControlPosition.TOP_LEFT].push(card);

    textInputButton.addEventListener('click', () => {
        void findPlaces(textInput.value);
    });

    textInput.addEventListener('keydown', (event) => {
        if (event.key === 'Enter') {
            void findPlaces(textInput.value);
        }
    });

    infoWindow = new InfoWindow();
}

async function findPlaces(query: string) {
    const [{ Place }, { AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('places'),
        google.maps.importLibrary('marker'),
    ]);

    const request = {
        textQuery: query,
        fields: ['displayName', 'location', 'businessStatus'],
        includedType: '', // Restrict query to a specific type (leave blank for any).
        useStrictTypeFiltering: true,
        locationRestriction: map.getBounds(),
        isOpenNow: true,
        language: 'en-US',
        maxResultCount: 8,
        minRating: 1, // Specify a minimum rating.
        region: 'us',
    };

    const { places } = await Place.searchByText(request);

    if (places.length) {
        const { LatLngBounds } = await google.maps.importLibrary('core');
        const bounds = new LatLngBounds();

        // First remove all existing markers.
        for (const id in markers) {
            markers[id].map = null;
        }
        markers = {};

        // Loop through and get all the results.
        places.forEach((place: google.maps.places.Place) => {
            const marker = new AdvancedMarkerElement({
                map,
                position: place.location,
                title: place.displayName,
                gmpClickable: true,
            });
            markers[place.id] = marker;

            marker.addEventListener('gmp-click', () => {
                map.panTo(place.location!);
                updateInfoWindow(place.displayName!, place.id, marker);
            });

            if (place.location != null) {
                bounds.extend(place.location);
            }
        });

        map.fitBounds(bounds);
    } else {
        console.log('No results');
    }
}

// Helper function to create an info window.
function updateInfoWindow(
    title: string | Element | null,
    content: string | Element | null,
    anchor: google.maps.marker.AdvancedMarkerElement
) {
    infoWindow.setContent(content);
    infoWindow.setHeaderContent(title);
    infoWindow.open({
        map,
        anchor,
        shouldFocus: false,
    });
}

void init();

JavaScript

let map;
let markers = {};
let infoWindow;

async function init() {
    const [{ Map, InfoWindow }, { ControlPosition }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('core'),
    ]);

    const center = { lat: 37.4161493, lng: -122.0812166 };
    map = new Map(document.getElementById('map'), {
        center,
        zoom: 11,
        mapTypeControl: false,
        mapId: 'DEMO_MAP_ID',
    });

    const textInput = document.getElementById('text-input');
    const textInputButton = document.getElementById('text-input-button');
    const card = document.getElementById('text-input-card');
    map.controls[ControlPosition.TOP_LEFT].push(card);

    textInputButton.addEventListener('click', () => {
        void findPlaces(textInput.value);
    });

    textInput.addEventListener('keydown', (event) => {
        if (event.key === 'Enter') {
            void findPlaces(textInput.value);
        }
    });

    infoWindow = new InfoWindow();
}

async function findPlaces(query) {
    const [{ Place }, { AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('places'),
        google.maps.importLibrary('marker'),
    ]);

    const request = {
        textQuery: query,
        fields: ['displayName', 'location', 'businessStatus'],
        includedType: '', // Restrict query to a specific type (leave blank for any).
        useStrictTypeFiltering: true,
        locationRestriction: map.getBounds(),
        isOpenNow: true,
        language: 'en-US',
        maxResultCount: 8,
        minRating: 1, // Specify a minimum rating.
        region: 'us',
    };

    const { places } = await Place.searchByText(request);

    if (places.length) {
        const { LatLngBounds } = await google.maps.importLibrary('core');
        const bounds = new LatLngBounds();

        // First remove all existing markers.
        for (const id in markers) {
            markers[id].map = null;
        }
        markers = {};

        // Loop through and get all the results.
        places.forEach((place) => {
            const marker = new AdvancedMarkerElement({
                map,
                position: place.location,
                title: place.displayName,
                gmpClickable: true,
            });
            markers[place.id] = marker;

            marker.addEventListener('gmp-click', () => {
                map.panTo(place.location);
                updateInfoWindow(place.displayName, place.id, marker);
            });

            if (place.location != null) {
                bounds.extend(place.location);
            }
        });

        map.fitBounds(bounds);
    } else {
        console.log('No results');
    }
}

// Helper function to create an info window.
function updateInfoWindow(title, content, anchor) {
    infoWindow.setContent(content);
    infoWindow.setHeaderContent(title);
    infoWindow.open({
        map,
        anchor,
        shouldFocus: false,
    });
}

void init();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
    height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#text-input-card {
    width: 25%;
    background-color: #fff;
    border-radius: 5px;
    box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
    margin: 10px;
    padding: 5px;
    font-family: Roboto, sans-serif;
    font-size: large;
    font-weight: bold;
}

#text-input {
    width: 100%;
    padding: 10px;
    margin: 0;
    box-sizing: border-box;
}

#text-input-button {
    display: inline-block;
    margin-top: 0.5rem;
    width: auto;
    padding: 0.6rem 0.75rem;
    font-size: 0.875rem;
    font-weight: 500;
    color: #fff;
    background-color: #2563eb;
    border: none;
    border-radius: 0.375rem;
    cursor: pointer;
    transition: background-color 0.15s ease-in-out;
    text-align: center;
}

HTML

<html>
    <head>
        <title>Text Search</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <script>
            // prettier-ignore
            (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
                key: "GOOGLE_MAPS_API_KEY"
            });
        </script>
    </head>
    <body>
        <div id="text-input-card">
            <input
                type="text"
                id="text-input"
                placeholder="Search for a place" />
            <input type="button" id="text-input-button" value="Search" />
        </div>
        <div id="map"></div>
    </body>
</html>

Örneği deneyin

Veri alanlarını seçme

İstediğiniz alanlar, her arama isteğinin fiyatını belirler. İstek, istenen alanlar arasında en yüksek SKU'da bir kez faturalandırılır. Örneğin, fields isteğine reviews eklendiğinde isteğin tamamı Text Search Enterprise + Atmosphere olarak faturalandırılır.

Arama isteklerini Text Search Pro'da tutmak için yalnızca arama sonuçlarınızda gösterilen alanları (ör. id, displayName, formattedAddress ve location) isteyin.

Kullanıcı bir yer seçtiğinde, reviews, nationalPhoneNumber veya websiteURI gibi alanları almak için ilgili yerde fetchFields() yöntemini çağırın. Her fetchFields() çağrısı, istediği alanlar arasında en yüksek SKU'da faturalandırılan ayrı bir Yer Ayrıntıları isteğidir. Bu yaklaşımın tasarruf sağlayıp sağlamayacağı, kullanıcılarınızın kaç yer açtığına bağlıdır.

Her SKU'yu tetikleyen alanlar

  • Aşağıdaki alanlar, Text Search Essentials (IDs Only) SKU'sunu tetikler:

    id

  • Aşağıdaki alanlar Text Search Pro SKU'yu tetikler:

    accessibilityOptions
    addressComponents
    adrFormatAddress
    businessStatus
    displayName
    formattedAddress
    googleMapsUri
    iconBackgroundColor
    location
    photos
    plusCode
    svgIconMaskURI
    types
    utcOffsetMinutes
    viewport

  • Aşağıdaki alanlar Text Search Enterprise SKU'sunu tetikler:

    internationalPhoneNumber
    nationalPhoneNumber
    priceLevel
    rating
    regularOpeningHours
    userRatingCount
    websiteURI

  • Aşağıdaki alanlar Text Search Enterprise + Atmosphere SKU'sunu tetikler:

    allowsDogs
    editorialSummary
    evChargeOptions
    fuelOptions
    hasCurbsidePickup
    hasDelivery
    hasDineIn
    hasLiveMusic
    hasMenuForChildren
    hasOutdoorSeating
    hasRestroom
    hasTakeout
    hasWifi
    isGoodForChildren
    isGoodForGroups
    isGoodForWatchingSports
    isReservable
    parkingOptions
    paymentOptions
    reviews
    servesBeer
    servesBreakfast
    servesBrunch
    servesCocktails
    servesCoffee
    servesDessert
    servesDinner
    servesLunch
    servesVegetarianFood
    servesWine

Her alanın SKU'su için Place sınıfı veri alanları bölümüne bakın.