我有一个API,可以根据订单号搜索信息,如下所示:
file_get_contents('https://www.example.com/api/status.php?os='.$orderId)
status.php
具有以下代码:
if (isset($_GET['os'])) { $orderId = strip_tags(htmlspecialchars($_GET['os'])); }
if (isset($orderId)) {
try {
$array = \JsonMachine\JsonMachine::fromFile($file);
// using JSON Machine https://github.com/halaxa/json-machine
$result = getOrderStatus($orderId, $array);
if (empty($result)) {
http_response_code(206);
} else {
echo json_encode($result, JSON_UNESCAPED_UNICODE);
}
} catch (Exception $e) {
echo json_encode(array(
'error' => array(
'code' => $e->getCode(),
'message' => $e->getMessage()
)
));
}
}
上面的代码加载json文件(当前为1.4MB,大约3000个对象,每个对象15个键/值对),然后将整个解码后的json传递给getOrderStatus
函数:
function getOrderStatus($orderId, $array) {
$resultArray = array();
foreach ($array as $val) {
$oid = explode(' ', $val['ORDER TITLE']);
$oid = $oid[0];
$oid = explode('_', $oid);
$oid = $oid[0];
if ($oid == $orderId) {
$resultArray['status'] = $val['STAT ID'];
$resultArray['email'] = $val['STAT CTRL'];
$resultArray['mzId'] = $val['ORDER ID'];
$resultArray['mcId'] = $val['COMPANY ID'];
$resultArray['count'] = $val['NUM PCS'];
}
}
return $resultArray;
}
if($ oid == $ orderId)是否匹配API中的ID是否与键“ ORDER TITLE”的值匹配,在这种情况下,该对象中的其余信息与搜索有关。
这是JSON文件中两个对象的示例:
[
{
"INTERNAL ID": "914693",
"ORDER TITLE": "0108491 A_PRODUCT_NAME",
"COMPANY ID": "",
"STAT ID": "1.2",
"STAT CTRL": "example@example.com",
"POST ID": "Post",
"SML": "Transfer",
"UPDATE": "17.06.2019 10:52:45",
"TOTAL": "0",
"NUM PCS": "1",
"PAID": "",
"TEXT": "",
"PROBLEM": ""
},
{
"INTERNAL ID": "914694",
"ORDER TITLE": "0108494 A_PRODUCT_NAME",
"COMPANY ID": "",
"STAT ID": "1.2",
"STAT CTRL": "example@example.com",
"POST ID": "Post",
"SML": "Transfer",
"UPDATE": "17.06.2019 10:52:45",
"TOTAL": "0",
"NUM PCS": "1",
"PAID": "",
"TEXT": "",
"PROBLEM": ""
}
]
问题是我无法控制JSON文件的格式,因为它是从外部软件导出的。
目前,我正在搜索和匹配大约。 100个订单号。这意味着,使用上面的代码,对于每个订单号-调用API,都需要打开JSON文件,测试了3000个对象中的每个对象是否匹配,并返回了包含信息的数组,所有100次。这就是为什么我认为该过程需要40秒的原因。尽管这是可以接受的,但将来JSON文件中的对象可能多达10倍。
如何使搜索速度更快?我当时想用一个订单号数组调用API,然后一次打开文件并匹配每个订单号。这是正确的方法吗?
答案 0 :(得分:0)
我最终要做的事情可能太复杂了,但是可以很好地达到目的,并且应该可以适应将来越来越大的json
主文件。对于某些背景:Web应用程序用于概述订单和有关订单的详细信息,这意味着需要触摸一些本地和外部API。约在任何给定时间可能有5个人(5个浏览器)正在使用该应用程序。
外部软件通过ftp上传包含大部分信息的大型json
文件。
要使整个过程自动化,我发现了incron
,它与cron
类似,但是它不是按时执行,而是按文件/目录操作(创建,更新,删除,等等。)。当然,这需要对本地服务器的ssh和root访问。
sudo apt install incron
incrontab -e
/route/to/json/file/big.json IN_CLOSE_WRITE /usr/bin/php /route/to/php/load.php
load.php
每次更改big.json
都会运行。
为了缩短加载时间,我创建了一个基于big.json
的带有列的数据库表。 load.php
读取big.json
并将每个对象保存为数据库表中的一行。现在,通过API提供此信息的代码部分现在从数据库而不是big.json
中读取该信息,如注释中所建议。这样将时间从原来的44秒减少到22秒。
尽管将json
转换为mysql
很有帮助,但我认为各个浏览器都不必继续重复加载过程,因此incron
的作用几乎相同,但是一次且仅在文件更改时。
load.php
可以过滤不需要的数据,还可以加载所有外部API并将数据与big.json
中的数据相关联地合并,然后将所有内容保存到名为data-full.json
的新文件中。此结果文件的大小比big.json
小16倍。然后,带有datatables.js
的浏览器应用程序会在几毫秒内加载此文件。
简而言之:
json
更新后才加载大型incron
文件json
文件转换为mysql
mysql
数据和外部API数据组合在一起json
中的“静态”新datatables.js
文件php
中用filemtime()
更新的时间戳记