@exabugs/dynamodb-client 1.3.41 → 1.3.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +1 -6
- package/dist/server/handler.cjs +91 -4
- package/dist/server/handler.cjs.map +3 -3
- package/dist/server/operations/updateMany.d.ts.map +1 -1
- package/dist/server/operations/updateMany.js +45 -2
- package/dist/server/operations/updateMany.js.map +1 -1
- package/dist/server/query/nearSearch.d.ts.map +1 -1
- package/dist/server/query/nearSearch.js +62 -0
- package/dist/server/query/nearSearch.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.3.43] - 2026-01-17
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **$near検索の最適化**: maxDistanceによる早期終了条件を追加
|
|
15
|
+
- 候補数による早期終了: maxDistance内の候補がlimit件以上見つかったら終了
|
|
16
|
+
- カバー範囲による早期終了: 現在の精度での9ブロック検索範囲がmaxDistanceを完全にカバーしたら終了
|
|
17
|
+
- GEOHASH_COVERAGE定義を拡張: Precision 2-8のカバー範囲を定義(従来は6-8のみ)
|
|
18
|
+
- 不要な精度緩和を削減し、検索パフォーマンスを向上
|
|
19
|
+
|
|
20
|
+
## [1.3.42] - 2026-01-15
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **ドット記法サポート**: `$set`オペレーターでドット記法(例: `"settings.locationEnabled"`)をサポート
|
|
25
|
+
- ネストされたオブジェクトとして正しく保存される(例: `settings: { locationEnabled: true }`)
|
|
26
|
+
- `expandDotNotation`ヘルパー関数を追加
|
|
27
|
+
- `applyJsonMergePatch`関数を更新してドット記法を展開
|
|
28
|
+
- ユニットテスト追加(10テスト)
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- **ドット記法の文字列キー問題**: `$set: { "settings.locationEnabled": true }`が文字列キーとして保存されていた問題を修正
|
|
33
|
+
- 以前: `{ "settings.locationEnabled": true }` (文字列キー)
|
|
34
|
+
- 修正後: `{ settings: { locationEnabled: true } }` (ネストされたオブジェクト)
|
|
35
|
+
|
|
10
36
|
## [1.3.41] - 2026-01-11
|
|
11
37
|
|
|
12
38
|
### Added
|
package/README.md
CHANGED
|
@@ -253,12 +253,7 @@ The easiest way to deploy is using the [dynamodb-client-example](https://github.
|
|
|
253
253
|
git clone https://github.com/exabugs/dynamodb-client-example.git
|
|
254
254
|
cd dynamodb-client-example
|
|
255
255
|
|
|
256
|
-
|
|
257
|
-
make deploy-dev
|
|
258
|
-
|
|
259
|
-
# Deploy to other environments
|
|
260
|
-
make deploy-stg # Staging
|
|
261
|
-
make deploy-prd # Production
|
|
256
|
+
make infra-apply
|
|
262
257
|
```
|
|
263
258
|
|
|
264
259
|
See the [example project's documentation](https://github.com/exabugs/dynamodb-client-example) for detailed deployment instructions.
|
package/dist/server/handler.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// @exabugs/dynamodb-client v1.3.
|
|
2
|
-
// Built: 2026-01-
|
|
1
|
+
// @exabugs/dynamodb-client v1.3.43
|
|
2
|
+
// Built: 2026-01-17T06:12:46.802Z
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -30053,6 +30053,13 @@ var init_converter = __esm({
|
|
|
30053
30053
|
});
|
|
30054
30054
|
|
|
30055
30055
|
// src/server/query/nearSearch.ts
|
|
30056
|
+
function coversMaxDistance(precision, maxDistance) {
|
|
30057
|
+
const coverage = GEOHASH_COVERAGE[precision];
|
|
30058
|
+
if (!coverage) {
|
|
30059
|
+
return false;
|
|
30060
|
+
}
|
|
30061
|
+
return coverage >= maxDistance;
|
|
30062
|
+
}
|
|
30056
30063
|
async function executeNearSearch(nearQuery, fieldName, limit, searchFunction, config = DEFAULT_GEOHASH_CONFIG) {
|
|
30057
30064
|
const { latitude, longitude } = extractCoordinatesFromNearQuery(nearQuery);
|
|
30058
30065
|
const maxDistance = extractMaxDistanceFromNearQuery(nearQuery);
|
|
@@ -30072,6 +30079,43 @@ async function executeNearSearch(nearQuery, fieldName, limit, searchFunction, co
|
|
|
30072
30079
|
allCandidates.push(candidate);
|
|
30073
30080
|
}
|
|
30074
30081
|
}
|
|
30082
|
+
if (maxDistance !== void 0) {
|
|
30083
|
+
let candidatesWithinDistance = 0;
|
|
30084
|
+
for (const candidate of allCandidates) {
|
|
30085
|
+
const location = candidate[fieldName];
|
|
30086
|
+
if (location && typeof location.latitude === "number" && typeof location.longitude === "number") {
|
|
30087
|
+
const distance = calculateDistance(
|
|
30088
|
+
latitude,
|
|
30089
|
+
longitude,
|
|
30090
|
+
location.latitude,
|
|
30091
|
+
location.longitude
|
|
30092
|
+
);
|
|
30093
|
+
if (distance <= maxDistance) {
|
|
30094
|
+
candidatesWithinDistance++;
|
|
30095
|
+
}
|
|
30096
|
+
}
|
|
30097
|
+
}
|
|
30098
|
+
if (candidatesWithinDistance >= limit) {
|
|
30099
|
+
console.log("[nearSearch] Early termination: found enough candidates within maxDistance", {
|
|
30100
|
+
candidatesWithinDistance,
|
|
30101
|
+
limit,
|
|
30102
|
+
maxDistance,
|
|
30103
|
+
precision,
|
|
30104
|
+
iterations
|
|
30105
|
+
});
|
|
30106
|
+
break;
|
|
30107
|
+
}
|
|
30108
|
+
if (coversMaxDistance(precision, maxDistance)) {
|
|
30109
|
+
console.log("[nearSearch] Early termination: current precision covers maxDistance", {
|
|
30110
|
+
precision,
|
|
30111
|
+
maxDistance,
|
|
30112
|
+
coverage: GEOHASH_COVERAGE[precision],
|
|
30113
|
+
candidatesWithinDistance,
|
|
30114
|
+
iterations
|
|
30115
|
+
});
|
|
30116
|
+
break;
|
|
30117
|
+
}
|
|
30118
|
+
}
|
|
30075
30119
|
precision--;
|
|
30076
30120
|
}
|
|
30077
30121
|
const documentsWithDistance = allCandidates.map((doc) => {
|
|
@@ -30120,10 +30164,28 @@ async function executeNearSearch(nearQuery, fieldName, limit, searchFunction, co
|
|
|
30120
30164
|
}
|
|
30121
30165
|
};
|
|
30122
30166
|
}
|
|
30167
|
+
var GEOHASH_COVERAGE;
|
|
30123
30168
|
var init_nearSearch = __esm({
|
|
30124
30169
|
"src/server/query/nearSearch.ts"() {
|
|
30125
30170
|
"use strict";
|
|
30126
30171
|
init_geohash();
|
|
30172
|
+
GEOHASH_COVERAGE = {
|
|
30173
|
+
8: 19 * 3,
|
|
30174
|
+
// ±19m × 3 = 約57m
|
|
30175
|
+
7: 76 * 3,
|
|
30176
|
+
// ±76m × 3 = 約228m
|
|
30177
|
+
6: 610 * 3,
|
|
30178
|
+
// ±610m × 3 = 約1,830m (1.8km)
|
|
30179
|
+
5: 2400 * 3,
|
|
30180
|
+
// ±2.4km × 3 = 約7,200m (7.2km)
|
|
30181
|
+
4: 2e4 * 3,
|
|
30182
|
+
// ±20km × 3 = 約60,000m (60km)
|
|
30183
|
+
3: 78e3 * 3,
|
|
30184
|
+
// ±78km × 3 = 約234,000m (234km)
|
|
30185
|
+
2: 63e4 * 3
|
|
30186
|
+
// ±630km × 3 = 約1,890,000m (1,890km)
|
|
30187
|
+
};
|
|
30188
|
+
__name(coversMaxDistance, "coversMaxDistance");
|
|
30127
30189
|
__name(executeNearSearch, "executeNearSearch");
|
|
30128
30190
|
}
|
|
30129
30191
|
});
|
|
@@ -31670,9 +31732,33 @@ var updateMany_exports = {};
|
|
|
31670
31732
|
__export(updateMany_exports, {
|
|
31671
31733
|
handleUpdateMany: () => handleUpdateMany
|
|
31672
31734
|
});
|
|
31735
|
+
function expandDotNotation(patch) {
|
|
31736
|
+
const result = {};
|
|
31737
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
31738
|
+
if (key.includes(".")) {
|
|
31739
|
+
const keys = key.split(".");
|
|
31740
|
+
let current = result;
|
|
31741
|
+
for (let i4 = 0; i4 < keys.length - 1; i4++) {
|
|
31742
|
+
const k4 = keys[i4];
|
|
31743
|
+
if (!(k4 in current)) {
|
|
31744
|
+
current[k4] = {};
|
|
31745
|
+
} else if (typeof current[k4] !== "object" || Array.isArray(current[k4])) {
|
|
31746
|
+
current[k4] = {};
|
|
31747
|
+
}
|
|
31748
|
+
current = current[k4];
|
|
31749
|
+
}
|
|
31750
|
+
const lastKey = keys[keys.length - 1];
|
|
31751
|
+
current[lastKey] = value;
|
|
31752
|
+
} else {
|
|
31753
|
+
result[key] = value;
|
|
31754
|
+
}
|
|
31755
|
+
}
|
|
31756
|
+
return result;
|
|
31757
|
+
}
|
|
31673
31758
|
function applyJsonMergePatch(target, patch) {
|
|
31759
|
+
const expandedPatch = expandDotNotation(patch);
|
|
31674
31760
|
const result = { ...target };
|
|
31675
|
-
for (const [key, value] of Object.entries(
|
|
31761
|
+
for (const [key, value] of Object.entries(expandedPatch)) {
|
|
31676
31762
|
if (value === null) {
|
|
31677
31763
|
delete result[key];
|
|
31678
31764
|
} else if (typeof value === "object" && !Array.isArray(value) && value !== null && typeof result[key] === "object" && !Array.isArray(result[key]) && result[key] !== null) {
|
|
@@ -32081,6 +32167,7 @@ var init_updateMany = __esm({
|
|
|
32081
32167
|
init_dynamodb3();
|
|
32082
32168
|
init_timestamps();
|
|
32083
32169
|
logger18 = createLogger({ service: "records-lambda" });
|
|
32170
|
+
__name(expandDotNotation, "expandDotNotation");
|
|
32084
32171
|
__name(applyJsonMergePatch, "applyJsonMergePatch");
|
|
32085
32172
|
__name(handleUpdateMany, "handleUpdateMany");
|
|
32086
32173
|
__name(getPreparationErrorCode2, "getPreparationErrorCode");
|
|
@@ -34020,7 +34107,7 @@ async function handler(event) {
|
|
|
34020
34107
|
return createCorsResponse(HTTP_STATUS.OK);
|
|
34021
34108
|
}
|
|
34022
34109
|
if (event.requestContext.http.method === "GET" && event.requestContext.http.path === "/version") {
|
|
34023
|
-
const version = "1.3.
|
|
34110
|
+
const version = "1.3.43";
|
|
34024
34111
|
return createSuccessResponse({ version, timestamp: (/* @__PURE__ */ new Date()).toISOString() }, requestId);
|
|
34025
34112
|
}
|
|
34026
34113
|
if (event.requestContext.http.method !== "POST") {
|