WordPress ACF Google 地图半径搜索

WordPress ACF Google Maps Radius Search

我遇到了一个大问题,没有解决方案。 我使用 WordPressCustom-Post-Type (CPT)Advanced Custom Fields (ACF)。 我创建了一个名为“projekt”的新 CPT 和一个 ACF“Google 地图字段”,它保存了 地址、经度和纬度 。坏事是 ACF 字段在 MySQL 数据库中被 序列化 保存。

我在网上找到了下面的SQL-计算半径的查询

$lat = '50.12335';
$lng = '-1.344453';
$radius = 10; // (km)  

???....WHERE ( 6371 * acos( cos( radians(" . $lat . ") ) 
* cos( radians( lat ) ) 
* cos( radians( lng ) 
- radians(" . $lng . ") ) 
+ sin( radians(" . $lat . ") ) 
* sin( radians( lat ) ) ) ) <= " . $radius . ")"

我不知道如何构建查询,因为查询需要从序列化的 ACF 字段中获取经度和纬度信息。

数据库字段“meta_value”:

a:13:{s:7:"address";s:44:"Moskauer Straße 5, Düsseldorf, Deutschland";s:3:"lat";d:51.2199565;s:3:"lng";d:6.8044928;s:4:"zoom";i:14;s:8:"place_id";s:114:"EiNNb3NrYXVlciBTdHIuLCBEw7xzc2VsZG9yZiwgR2VybWFueSIuKiwKFAoSCZV-jR3Ny7hHEVVgUQUBF7q8EhQKEgkBGQXwtsu4RxHgwS1K_GAnBQ";s:4:"name";s:16:"Moskauer Straße";s:11:"street_name";s:16:"Moskauer Straße";s:17:"street_name_short";s:13:"Moskauer Str.";s:4:"city";s:11:"Düsseldorf";s:5:"state";s:19:"Nordrhein-Westfalen";s:11:"state_short";s:3:"NRW";s:7:"country";s:11:"Deutschland";s:13:"country_short";s:2:"DE";}

我可以得到我所有的“projekt”:

也许可以扩展以下查询

SELECT P.ID, P.post_title, P.post_content, P.post_author, meta_value
FROM wp_posts AS P
LEFT JOIN wp_postmeta AS PM on PM.post_id = P.ID
WHERE P.post_type = 'projekt' and P.post_status = 'publish' and ( meta_key = 'adress' )
ORDER BY P.post_date DESC

结果是:

ID|post_title  |post_content|post_author|meta_value
55|Test Projekt|            |1          |a:13:{s:7:"address";s:44:"Moskauer Straße 5, Düss...

你有什么解决方案吗?

谢谢!

好的,所以这看起来很讨厌,但在不添加半径部分的测试中,我能够从序列化数据中提取 latlng

所以我认为您可以将半径检查添加为 AND 如下所示:

SELECT 
  REPLACE(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(pm.meta_value, 'lat', -1), ';', 2), ':', -1), '"', '') AS latitude,
  REPLACE(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(pm.meta_value, 'lng', -1), ';', 2), ':', -1), '"', '') AS longitude
FROM wp_postmeta pm
WHERE pm.meta_key = 'change_to_your_meta_key'
AND ( 6371 * acos( cos( radians(" . $lat . ") ) 
* cos( radians( latitude ) ) 
* cos( radians( longitude ) 
- radians(" . $lng . ") ) 
+ sin( radians(" . $lat . ") ) 
* sin( radians( longitude ) ) ) ) <= " . $radius . ")"

我自己找到了解决方案。 大多数人,用纬度和经度创建额外的表。 我认为这毫无意义,因为它们已经存在于 acf 领域。 我在 MySQL 方面不是很熟练,所以有些人当然可以缩短查询。 我不知道如何在 MySQL 中使用变量,所以可以将经纬度的正则表达式放入变量中:

REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lat\";d:([0-9\.]+).+','\1') AS latitude

REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lng\";d:([0-9\.]+).+','\1') AS longitude

这里是 Radius Search with WordPress、ACF(Google 地图字段)的完整查询,其中 INPUTLAT、INPUTLONG、INPUTKM 是您提供的值:

SELECT P.ID, P.post_title, P.post_content, P.post_author,
    IF(PM.meta_key = 'adress', PM.meta_value, NULL) AS adress,
    REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lat\";d:([0-9\.]+).+','\1') AS latitude,
    REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lng\";d:([0-9\.]+).+','\1') AS longitude
FROM wp_posts AS P
LEFT JOIN wp_postmeta AS PM on PM.post_id = P.ID
WHERE P.post_type = 'projekt' and P.post_status = 'publish' and IF(PM.meta_key = 'adress', PM.meta_value, NULL) IS NOT NULL and IF(PM.meta_key = 'adress', PM.meta_value, NULL) IS NOT NULL AND 
( 6371 * acos( cos( radians(INPUTLAT) ) 
* cos( radians( REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lat\";d:([0-9\.]+).+','\1') ) ) 
* cos( radians( REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lng\";d:([0-9\.]+).+','\1') ) 
- radians(INPUTLONG) ) 
+ sin( radians(INPUTLAT) ) 
* sin( radians( REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lat\";d:([0-9\.]+).+','\1') ) ) ) ) <= INPUTKM 
ORDER BY P.post_date DESC

这就在MariaDB工作或者MySQL 8. MySQL 5不知道REGEX_REPLACE