Betapa mudahnya mengirimkan pesanan, mengetahui alamat pelanggan (tidak terlalu)

Halo semuanya! Nama saya Denis Girko, saya adalah arsitek sistem platform e-commerce di Lamoda. Tahun lalu saya berbicara di konferensi DevConf dengan sebuah laporan yang ingin saya bagikan dengan Anda.


Ini adalah laporan ulasan tentang kesulitan yang dihadapi sebuah toko online besar dalam proses pengiriman pesanan dan solusi teknis apa yang dapat membantu mengatasinya (menggunakan solusi yang kami uji di Lamoda sebagai contoh).


gambar


Tentang apa ini? Saya akan memberi tahu Anda:


  • Tentang proses pengiriman dan mengidentifikasi masalah;
  • cara menyimpan wilayah pengiriman secara efektif dalam basis data;
  • cara meningkatkan kualitas data yang kami terima dari klien;
  • cara mencari penerima di basis data alamat untuk menemukan hasil yang lebih akurat.

Skema Pengiriman Pesanan Lamoda Umum


Lamoda adalah toko online dengan empat negara pengiriman: Rusia, Ukraina, Kazakhstan, Belarus. Kami mengirimkan barang keesokan harinya karena fakta bahwa kami memiliki layanan pengiriman sendiri dan selusin mitra pihak ketiga yang layanannya kami gunakan. Pengiriman adalah bagian besar dari bisnis kami.


Lamoda menerima pesanan, meminta klien untuk alamat pada saat pendaftaran dan meneruskannya ke layanan kurir.


gambar


Bagaimana jika kita tidak memiliki satu layanan kurir, tetapi beberapa? Kemudian langkah selanjutnya ditambahkan - untuk menentukan layanan pengiriman mana kami akan mengambil pesanan.


gambar


Mungkin ada beberapa kriteria pemilihan bisnis. Tetapi hal pertama yang harus dipikirkan adalah apakah layanan kurir ini memiliki pengiriman ke kota yang dipilih oleh klien atau tidak. Oleh karena itu, langkah pertama dalam mengintegrasikan perusahaan kurir ke dalam sistem kami adalah menemukan area jangkauannya.
gambar
Selanjutnya, Anda perlu mempelajari cara memeriksa apakah alamat klien termasuk dalam wilayah ini atau tidak.


Skema umum akan ditingkatkan dan akan terlihat seperti ini:


  • minta alamat;
  • mencari tahu layanan kurir mana yang dapat memberikannya;
  • pilih yang Anda inginkan dari yang tersedia.

gambar


Sekarang sedikit lebih banyak tentang langkah-langkah ini.


Kami meminta alamat klien


Bagaimana saya bisa bertanya padanya?


  1. Mintalah untuk mengisi satu bidang besar. Klien palu di alamatnya, yang selanjutnya tidak perlu manipulasi rumit. Alamat tersebut dapat dicetak pada selembar kertas, diberikan kepada kurir dengan berjalan kaki, yang kemudian akan mencari tahu sendiri.
  2. Opsi kedua lebih rumit. Kami meminta klien untuk mengisi setiap komponen alamat di bidangnya. Di sini Anda sudah dapat melakukan sesuatu. Misalnya, bandingkan kota Moskow dengan daftar kota yang diberikan. Tetapi itu akan bekerja dengan buruk, karena kota Moskow dapat ditulis dengan banyak cara: “g. Moskow "," kota Moskow "," kota Moskow "tanpa spasi, dan seterusnya.
  3. Oleh karena itu, ada opsi yang lebih maju. Karena daftar kota yang kita miliki terbatas, Anda dapat melakukan pra-kompilasi daftar kota dan menyarankan agar klien memilih yang dia butuhkan. Bonusnya adalah bahwa untuk setiap elemen daftar seperti itu kita sudah dapat mengaitkan beberapa pengidentifikasi di sini. Kami pengembang senang bekerja bukan dengan string, tetapi dengan pengidentifikasi yang dapat digunakan di semua sistem kami sebagai setara dengan kota yang dipilih. Saya memiliki indeks kantor pos pusat di slide sebagai pengenal.
    gambar

Layanan pengiriman apa yang kamiangkut?


Karena kami memiliki pengidentifikasi (indeks), maka biarkan wilayah yang disimpan dalam database kami diwakili oleh daftar indeks. Dalam hal ini, algoritma untuk memeriksa masuknya kota ke wilayah tersebut sangat sederhana. Jadi mari kita lakukan: kita akan menempatkan wilayah pengiriman yang diterima dari layanan kurir dalam database dalam bentuk indeks.


Indeks memiliki pro dan kontra mereka. Saya akan mengatakan sebelumnya bahwa pada awalnya Lamoda melakukan hal itu: hasil memilih klien kota adalah indeks, dan indeks kami disimpan dalam database. Mengapa ditambah? Seperti yang saya katakan, indeks adalah hal yang dipahami semua orang. Setiap manajer yang baru saja datang bekerja tahu apa itu indeks. Dia dapat menerima dari perusahaan kurir kota, entah bagaimana mengubahnya menjadi indeks dan digunakan. Kelemahannya adalah bahwa indeks tersebut adalah pengidentifikasi Kantor Pos dari Pos Rusia. Dan permukiman terdekat dapat berbagi indeks yang sama.


Mengapa indeks hilang?


Contoh sederhana: Lyubertsy. Terdekat adalah desa Marusino. Marusino tidak memiliki kantor pos, korespondensi mereka datang ke salah satu kantor pos Lyubertsy. Jika kami ingin menambahkan pengiriman ke Lyubertsy, tetapi tidak mengirimkannya ke Marusino, karena mungkin tidak menguntungkan secara finansial bagi kami, kami tidak akan dapat melakukan ini hanya dengan indeks.
gambar


Contoh lain adalah ketika Lamoda memperluas dan membuka gudang transit kedua di Moskow. Itu perlu untuk membagi Moskow menjadi bagian utara dan selatan. Dan sudah pada saat melakukan pemesanan, pahami dari gudang transit mana pengiriman akan dilakukan. Dalam hal ini, satu indeks per kota tidak akan cukup.


Kami memutuskan untuk menggunakan koordinat geografis bersama dengan indeks. Kami mengambil alamat klien, menjalankannya melalui geocoder Yandex . Pada output, kami mendapatkan tidak hanya indeks, tetapi juga koordinat. Kami menggunakan indeks jika detail tidak penting. Dan koordinat menentukan kasus-kasus ketika Anda perlu membuat pembagian wilayah yang tipis.


Mereka menyediakan antarmuka dalam program pengaturan mereka untuk ahli logistik, yang memungkinkan Anda untuk menggambar poligon di atas peta. Sederhana: intinya jatuh ke TPA - ada pengiriman, tidak jatuh - tidak.
gambar
Antarmuka Pembuatan Zona Polygon


Bonus yang kami miliki memiliki koordinat geografis untuk setiap pesanan adalah kesempatan untuk meningkatkan antarmuka yang digunakan para ahli logistik untuk membuat rute bagi perwakilan penjualan. Antarmuka menampilkan peta di mana pesanan pelanggan ditandai. Logistician menggunakan alat laso, yang menggabungkan pesanan yang berdekatan menjadi satu rute. Lebih jauh lagi, rute ini menuju ke salah satu perwakilan penjualan, yaitu, seseorang tidak perlu pergi dari satu ujung kota ke ujung lainnya pada siang hari untuk mengambil semua pesanannya - mereka semua secara geografis dekat.
gambar
Antarmuka perutean


Alamat yang dimasukkan oleh klien dikonversi ke koordinat. Kemungkinan kita akan mendapatkan koordinat untuk alamat yang diberikan secara langsung tergantung pada kualitas alamat yang dimasukkan oleh klien. Karena itu, hal pertama yang kami pikirkan adalah bagaimana meningkatkan jumlah alamat yang dikenal baik. Karena itu, Anda perlu membantu pelanggan memasukkan alamat yang benar.


Faktanya adalah bahwa pelanggan sering tidak mengikuti skenario yang kami sediakan untuk mereka, jadi kami memperoleh basis data alamat untuk masing-masing dari 4 negara tempat kami mengirimkan pesanan. Dan mereka membuat sajest tidak hanya untuk kota, tetapi juga untuk jalan, dan bahkan untuk nomor rumah. Untuk membuat daftar rumah, kami mem- parsing data terbuka openstreetmap.org .
gambar
Formulir checkout menawarkan tip untuk memformalkan data alamat


Alamat dasar


Untuk melakukan sujest di basis alamat, Anda harus menyimpannya di rumah. Dari mana kami mendapatkan semua basis alamat untuk empat negara kami? Di Rusia, FIAS , basis alamat yang dikompilasi dan dikelola oleh layanan pajak kami. Ini cukup lengkap, meski bukan tanpa cacat. Mitra pengiriman kami telah membantu kami dengan negara lain.
gambar


Kami juga memiliki satu set skrip PHP yang mengambil format yang menjadi basis alamat kami, dan dengan cara yang sama menambahkannya ke PostgreSQL . Kenapa dalam bentuk yang sama? Karena salah satu tugas adalah memperbarui basis data ini secara berkala dari sumber yang sama. Ini berarti bahwa jika kami menyediakan untuk konversi, itu harus diulang dengan setiap pembaruan. Dengan demikian, data masuk ke PostgreSQL, dan dari sana itu dikonversi dan disimpan di Apache Solr ; Solr memungkinkan Anda untuk mencari mereka dengan cepat dan melakukan sajest. Sebuah server web PHP kecil dapat membuat permintaan di Solr, menurut hasil mereka, sebuah daftar dibuat untuk klien di situs untuk yang paling besar.


Contoh hidup

gambar


gambar


Kami mengunduh data dari sumber dalam bentuk yang kira-kira sama dengan saat mereka datang kepada kami. Yaitu, dengan kumpulan bidang yang sama, dengan jenis kolom yang sama, dan seterusnya. Tambahkan mereka apa adanya. Kami mencoba menggunakan data dalam bentuk ini sejak awal, dan untuk mengubahnya menjadi struktur yang dapat kami gunakan, kami menulis beberapa tampilan. Karena kita memiliki 4 negara, semua ini dikalikan dengan 4, dan itu sangat sulit dan mahal untuk didukung. Karena itu, perlu untuk melakukan sesuatu tentang itu.


Hal pertama yang kami singkirkan adalah tidak terstruktur, atau lebih tepatnya, terstruktur khusus , pada tahap awal. Yaitu, segera setelah data mentah telah diunggah, dengan bantuan tampilan kami mengubahnya menjadi format yang disatukan, yang dengannya semua transformasi kami yang lain dikonfigurasi lebih lanjut. Ini menyelamatkan kita dari perkalian dengan 4. Dan pada saat inilah kita lupa tentang struktur di mana data datang kepada kita, dan kita bekerja hanya dengan apa yang telah kita ciptakan untuk diri kita sendiri.
gambar


Jika Anda memerlukan dua sumber - silakan unduh. Yang utama adalah bahwa format output data ini setelah konversi ke tampilan adalah sama.
gambar


Persyaratan lain untuk basis data alamat yang dimuat adalah bahwa perlu untuk melakukan koreksi poin. Contoh sederhana: di FIAS, Republik Chuvash disebut “Chuvash Rep. "Chuvashia." Yah, kami hanya menginginkan Republik Chuvash. Mengapa kita membutuhkan tanda hubung ini? Dan pada saat yang sama, kami masih tidak dapat menghindari pembaruan berkala dari sumber.


Berikut adalah lapisan-lapisan berikut yang kami miliki di PostgreSQL.
gambar


Tabel di sebelah kiri adalah data mentah yang diunduh dari sumbernya.


Di belakangnya terdapat tampilan yang mengubah data ke format standar.


Overridings lokal - kami memiliki satu set tabel yang menentukan ulang beberapa atribut dari data alamat yang dimuat. Kami telah memasukkan di sini, misalnya, bahwa catatan dengan pengidentifikasi seperti itu harus menerima alih-alih “rep Chuvash. - Chuvashia ”adalah nama pilihan kami.


Tabel pemetaan adalah repositori pengidentifikasi kami, yang kami tetapkan sendiri untuk objek alamat yang kami unduh - ini memungkinkan kami untuk mengabstraksi sistem kami dari sumber, dari pengidentifikasi yang digunakan dalam sumber, dan juga untuk menyembunyikan tidak satu sumber, tetapi bahkan beberapa - di bawah satu ID Saya akan memberi tahu nanti. Semua ini digabungkan dan diperbaiki dalam tampilan terwujud. Jadi, kita mendapatkan hampir setara dengan tabel final, yang dapat diperbarui dengan menjalankan satu perintah SQL REFRESH MATERIALIZED VIEW .


Objek alamat - basis alamat yang dibentuk dengan semua koreksi dan penambahan.


Jadi, pada output kita sudah mengoreksi objek alamat, sudah dengan nama baru dan pengidentifikasi kami. Semua ini diubah dan didenormalisasi, mudah digunakan untuk pencarian, dan ditambahkan dalam Solr.


Karena sekarang kami memiliki basis data alamat, akan lebih baik untuk menggunakannya tidak hanya untuk membuat sujest untuk formulir pemesanan, tetapi juga untuk melakukan pencarian. Di mana pencarian bisa berguna? Ternyata banyak kemana. Area pengiriman yang sama yang kami terima dari layanan kurir sangat sering diwakili hanya dengan daftar kota. Dan daftar kota dipenuhi dengan masalah yang sama dengan input pengguna: kota dapat memiliki interpretasi yang berbeda, nama yang berbeda, dan banyak lagi.


Saya punya slide khusus di sini, seperti kisah horor - apa yang harus kita lakukan jika kita mengambil semuanya secara manual untuk mengubahnya menjadi PHP: yaitu, Chechnya, Republik Chechen, dan untuk setiap sumber data - neraka adalah neraka.


gambar


Tambahan: Di layar - sepotong kode nyata dari layanan, yang menjadi tidak perlu hanya karena solusi yang dijelaskan.

Kami telah mengklasifikasikan masalah ini.


1) Nama yang setara dari objek yang sama. Misalnya, sinonim umum seperti Chuvashia dan Republik Chuvash.


2) Berganti nama kota. Ukraina sekarang berada dalam fase aktif untuk menyingkirkan masa lalu komunis, itulah sebabnya mereka setiap hari benar-benar melakukan perubahan nama-nama pemukiman mereka. Untuk alasan ini, mungkin ternyata dalam satu database kami memiliki nama lama, dan yang lain - yang baru.


3) Banyak kesalahan. Sering keliru dalam status pemukiman. Ada sebuah desa, di sini ada sebuah desa atau di sini ada sebuah desa, ada sebuah peternakan.


4) Kata-kata asing yang ditransliterasikan ke dalam bahasa Rusia, seringkali nama yang sama ditransliterasikan dengan berbagai cara.


5) Ada banyak kesalahan dalam hierarki: Zelenograd, berdasarkan kebiasaan, adalah milik wilayah Moskow, meskipun secara resmi juga terdaftar di Moskow sebagai FIAS. Tulis dengan benar "Kota Moskow, Zelenograd."


Bagaimana kita menemukan ini?


Hal pertama yang kami lakukan adalah memisahkan semua komponen alamat yang tidak penting dari namanya. Kami tidak membuangnya, mereka berpartisipasi dalam pencarian, tetapi terpisah dari bagian-bagian penting.
gambar


Selanjutnya, kami membuat daftar pendek sinonim dan singkatan umum yang digunakan dalam nama. Di mana sumber diizinkan, kami memuat dan memasukkan semua nama ke Solr. Bukan hanya yang paling relevan, tetapi juga kemungkinan sinonim dan nama historis.


Untuk pencarian yang lebih baik, kami membuang semua surat yang dapat menyebabkan perbedaan. Ini berlaku untuk bahasa Rusia dan bahasa-bahasa yang masih harus kita tangani.


Kami memperbaiki kesalahan ketik dan memperbaiki tata letak.


Akhirnya, kami datang dengan orang tua hantu - ini adalah orang tua yang ditugaskan untuk objek. Mereka relevan dalam pencarian, tetapi tidak berpartisipasi dalam hasil pencarian. Misalnya, untuk Zelenograd, kami menambahkan wilayah Moskow. Sekarang Anda dapat mencari "Wilayah Moskow, Zelenograd" dan menemukan objek yang kami butuhkan, tetapi dalam hasil pencarian itu masih akan menjadi "Moskow, Zelenograd" yang benar.


gambar


Bergantung pada persyaratan bisnis, diperlukan gradasi akurasi pencarian yang berbeda. Oleh karena itu, kami memiliki 4 derajat, masing-masing memberikan hasil dengan probabilitas yang lebih tinggi, tetapi dengan probabilitas yang lebih rendah itu akan persis hasil yang dicari.
gambar


Dan di mana kami menemukan aplikasi pencarian seperti itu?


  • Sekali lagi, kami menjalankan alamat yang dimasukkan oleh klien melalui pencarian seperti itu. Jika dia tidak menggunakan tips kami di halaman checkout, maka kita memiliki satu kesempatan lagi untuk mengubah garis yang dia masukkan menjadi pengidentifikasi. Kami mendapatkan alamat yang diformalkan.
  • Kami menjalankan semua pencarian yang dikirim oleh jasa kurir kami - kami mengenali kota-kota yang mereka kirimkan kepada kami. Ini memungkinkan kami untuk meluncurkan hanya 10 buah sehari, ini relevan untuk B2B - Lamoda menyediakan pengirimannya ke perusahaan pihak ketiga, jadi ada banyak layanan kurir baru yang terhubung per unit waktu.
  • Ini memungkinkan kami untuk "merangkai" berbagai informasi yang berguna ke dalam pengidentifikasi kami di basis data alamat. Misalnya, kami mengunduh zona waktu, alamat IP, untuk mencari kota berdasarkan alamat IP klien.
  • Kami sekarang memiliki kesempatan untuk menyembunyikan basis alamat yang digabungkan dari dua sumber dengan salah satu pengidentifikasi kami. Artinya, itu memungkinkan menghindari duplikat dan mencocokkan objek alamat yang sama di kedua pangkalan.

Kami tidak berhenti. Ini adalah proses yang masih bisa kita tingkatkan.


Pertama, Lamoda bekerja pada indeks. Artinya, pengidentifikasi kami adalah indeks, yang kami ketahui kekurangannya. Hampir semua sistem kami telah beralih ke API baru, mereka beroperasi bukan dengan indeks, tetapi dengan pengidentifikasi yang kami sendiri ditugaskan untuk objek alamat kami. Nilai tambahnya adalah memeriksa kota di wilayah itu sesederhana dengan indeks. Namun, tidak ada minus dalam kenyataan bahwa beberapa pemukiman dapat bersembunyi di balik satu ID.


Tambahan: Waktu telah berlalu sejak saat pidato saya, dan sekarang saya senang untuk memperbaiki diri: indeks kami sekarang hanya tersisa dalam kasus ini, ketika kurir memberi kami wilayahnya dalam bentuk daftar mereka, misalnya, Russian Post. Dalam kasus lain, indeks digantikan oleh pengidentifikasi alamat internal kami.

Pada slide adalah bagian dari antarmuka yang memungkinkan Anda untuk mengkonfigurasi wilayah secara manual, tetapi pada kenyataannya semuanya dikonfigurasi dari daftar objek alamat yang dimuat dalam bentuk string.
gambar


Kami mengunduh koordinat geografis dari openstreetmap.org untuk rumah. Sekarang, dalam persentase besar kasus, kita tidak perlu pergi ke layanan eksternal untuk mengetahui lokasi. Ini mengurangi kami 10 kali perjalanan ke Yandex, yang tentu saja menghemat uang.


Kami menyingkirkan PHP di rantai pencarian untuk data alamat. Kami menulis ulang kode yang mengakses Solr pada Lua. Digantikan nginx dengan Openresty , sekarang semuanya sangat cepat dan dapat menahan beban berat. 95% dari tanggapan layanan pencarian kami cocok dalam 10 milidetik, yang lebih dari cukup bagi kami.


gambar


Tambahan: Menggunakan Openresty dan Lua, yang menarik dengan kinerja mereka, adalah semacam eksperimen yang terbayar: layanan bekerja dengan cepat, stabil di bawah beban, dan mudah dipelihara. Namun sejak itu, Lamoda telah mengadopsi Golang, yang memiliki kualitas yang sama, sebagai salah satu bahasa pemrograman untuk backend yang dimuat. Jika keputusan untuk mengembangkan layanan dibuat sekarang, kami lebih suka itu.

Kesimpulan


Moralitas pribadi saya dari semua pekerjaan yang dilakukan adalah bahwa data alamat adalah area di mana Anda tidak dapat mengharapkan kualitas data yang ideal. Ini tidak akan pernah terjadi. Kami tidak akan pernah menerima data sempurna dari pelanggan atau dari sumber eksternal. Karena itu, Anda harus memeras maksimal dari apa yang ada.

Source: https://habr.com/ru/post/id444848/


All Articles