@exabugs/dynamodb-client 1.3.42 → 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 CHANGED
@@ -7,6 +7,16 @@ 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
+
10
20
  ## [1.3.42] - 2026-01-15
11
21
 
12
22
  ### 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
- # Deploy to dev environment
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.
@@ -1,5 +1,5 @@
1
- // @exabugs/dynamodb-client v1.3.42
2
- // Built: 2026-01-15T00:42:00.085Z
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
  });
@@ -34045,7 +34107,7 @@ async function handler(event) {
34045
34107
  return createCorsResponse(HTTP_STATUS.OK);
34046
34108
  }
34047
34109
  if (event.requestContext.http.method === "GET" && event.requestContext.http.path === "/version") {
34048
- const version = "1.3.42";
34110
+ const version = "1.3.43";
34049
34111
  return createSuccessResponse({ version, timestamp: (/* @__PURE__ */ new Date()).toISOString() }, requestId);
34050
34112
  }
34051
34113
  if (event.requestContext.http.method !== "POST") {