ninegrid2 6.529.0 → 6.531.0
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/dist/ai/aiContainer.js +122 -9
- package/dist/bundle.cjs.js +117 -9
- package/dist/bundle.esm.js +117 -9
- package/package.json +1 -1
- package/src/ai/aiContainer.js +122 -9
package/dist/ai/aiContainer.js
CHANGED
|
@@ -48,9 +48,8 @@ class aiContainer extends HTMLElement
|
|
|
48
48
|
</div>
|
|
49
49
|
<div class="menu">
|
|
50
50
|
<div class="collapse-icon"></div>
|
|
51
|
-
<div class="menu-icon menu-filter"></div>
|
|
52
|
-
<div class="menu-icon menu-general
|
|
53
|
-
<div class="menu-icon menu-db"></div>
|
|
51
|
+
<div class="menu-icon menu-filter" active></div>
|
|
52
|
+
<div class="menu-icon menu-general"></div>
|
|
54
53
|
<div class="menu-icon menu-setting"></div>
|
|
55
54
|
</div>
|
|
56
55
|
</div>
|
|
@@ -116,6 +115,12 @@ class aiContainer extends HTMLElement
|
|
|
116
115
|
}
|
|
117
116
|
};
|
|
118
117
|
|
|
118
|
+
#getData = () => {
|
|
119
|
+
if (this.#target.tagName === "NINE-GRID") {
|
|
120
|
+
return this.#target.data.get();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
119
124
|
|
|
120
125
|
#generateQdrantFilter = async () => {
|
|
121
126
|
|
|
@@ -230,11 +235,123 @@ class aiContainer extends HTMLElement
|
|
|
230
235
|
// console.error("Error during Qdrant search:", error);
|
|
231
236
|
return [];
|
|
232
237
|
//}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Qdrant 필터링 조건에 따라 JSON 배열을 필터링하는 함수입니다.
|
|
242
|
+
*
|
|
243
|
+
* @param {Array<Object>} jsonArray 필터링할 JSON 객체 배열입니다.
|
|
244
|
+
* @param {Object} filter 필터링 조건 객체입니다. Qdrant 필터와 유사한 구조를 가집니다.
|
|
245
|
+
* 예시:
|
|
246
|
+
* {
|
|
247
|
+
* must: [ // 모든 조건이 참이어야 함
|
|
248
|
+
* { key: "field1", match: { value: "some_value" } },
|
|
249
|
+
* { key: "field2", range: { gte: 10, lt: 20 } }
|
|
250
|
+
* ],
|
|
251
|
+
* should: [ // 하나 이상의 조건이 참이어야 함
|
|
252
|
+
* { key: "field3", match: { value: "another_value" } },
|
|
253
|
+
* { key: "field4", match: { any: ["valueA", "valueB"] } }
|
|
254
|
+
* ],
|
|
255
|
+
* must_not: [ // 어떤 조건도 참이 아니어야 함
|
|
256
|
+
* { key: "field5", match: { value: "excluded_value" } }
|
|
257
|
+
* ]
|
|
258
|
+
* }
|
|
259
|
+
* @returns {Array<Object>} 필터링된 JSON 객체 배열입니다.
|
|
260
|
+
*/
|
|
261
|
+
#filterJsonArray = (jsonArray, filter) => {
|
|
262
|
+
if (!jsonArray || !Array.isArray(jsonArray)) {
|
|
263
|
+
console.error("첫 번째 인수는 JSON 배열이어야 합니다.");
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
if (!filter || typeof filter !== 'object') {
|
|
267
|
+
// 필터 조건이 없거나 유효하지 않으면 원본 배열 반환
|
|
268
|
+
return jsonArray;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return jsonArray.filter(item => {
|
|
272
|
+
// 'must' 조건 처리: 모든 'must' 조건이 참이어야 합니다.
|
|
273
|
+
if (filter.must && !filter.must.every(condition => this.#evaluateCondition(item, condition))) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// 'should' 조건 처리: 하나 이상의 'should' 조건이 참이어야 합니다.
|
|
278
|
+
// 'should' 조건이 없으면 이 부분은 건너뜁니다.
|
|
279
|
+
if (filter.should && filter.should.length > 0 && !filter.should.some(condition => this.#evaluateCondition(item, condition))) {
|
|
280
|
+
return false;
|
|
281
|
+
} else if (filter.should && filter.should.length === 0 && (filter.must || filter.must_not)) {
|
|
282
|
+
// 'should'가 비어있고 'must'나 'must_not'가 있으면 'should'는 필터링에 영향 없음.
|
|
283
|
+
// 하지만 'should'만 있고 비어있다면, 사실상 필터링이 안 되는 것과 같으므로 true 반환.
|
|
284
|
+
// 이 로직은 Qdrant의 'should'가 비어있을 때의 동작과 일치하도록 조정될 수 있습니다.
|
|
285
|
+
// 현재는 'should'가 비어있으면 필터링에 영향이 없도록 합니다.
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
// 'must_not' 조건 처리: 어떤 'must_not' 조건도 참이 아니어야 합니다.
|
|
290
|
+
if (filter.must_not && filter.must_not.some(condition => this.#evaluateCondition(item, condition))) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return true;
|
|
295
|
+
});
|
|
233
296
|
}
|
|
234
297
|
|
|
298
|
+
/**
|
|
299
|
+
* 단일 필터링 조건을 평가하는 헬퍼 함수입니다.
|
|
300
|
+
* @param {Object} item 현재 평가 중인 JSON 객체입니다.
|
|
301
|
+
* @param {Object} condition 평가할 단일 조건입니다. (예: { key: "field1", match: { value: "some_value" } })
|
|
302
|
+
* @returns {boolean} 조건이 참이면 true, 그렇지 않으면 false.
|
|
303
|
+
*/
|
|
304
|
+
#evaluateCondition = (item, condition) => {
|
|
305
|
+
const valueInItem = item[condition.key];
|
|
306
|
+
|
|
307
|
+
if (condition.match) {
|
|
308
|
+
const match = condition.match;
|
|
309
|
+
if (match.value !== undefined) {
|
|
310
|
+
return valueInItem === match.value;
|
|
311
|
+
}
|
|
312
|
+
if (match.any && Array.isArray(match.any)) {
|
|
313
|
+
return match.any.includes(valueInItem);
|
|
314
|
+
}
|
|
315
|
+
if (match.all && Array.isArray(match.all)) {
|
|
316
|
+
// item[condition.key]가 배열이라고 가정
|
|
317
|
+
if (!Array.isArray(valueInItem)) return false;
|
|
318
|
+
return match.all.every(val => valueInItem.includes(val));
|
|
319
|
+
}
|
|
320
|
+
if (match.text !== undefined) {
|
|
321
|
+
// 텍스트 매치는 부분 문자열 일치 또는 정규식 등으로 확장 가능
|
|
322
|
+
// 여기서는 단순 포함 여부로 구현
|
|
323
|
+
return typeof valueInItem === 'string' && valueInItem.includes(match.text);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (condition.range) {
|
|
328
|
+
const range = condition.range;
|
|
329
|
+
if (typeof valueInItem !== 'number') return false; // 숫자가 아니면 범위 비교 불가
|
|
330
|
+
|
|
331
|
+
if (range.gte !== undefined && !(valueInItem >= range.gte)) return false;
|
|
332
|
+
if (range.gt !== undefined && !(valueInItem > range.gt)) return false;
|
|
333
|
+
if (range.lte !== undefined && !(valueInItem <= range.lte)) return false;
|
|
334
|
+
if (range.lt !== undefined && !(valueInItem < range.lt)) return false;
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// 다른 필터 타입 (예: `geo_bounding_box`, `has_id` 등)은 필요에 따라 추가 구현
|
|
339
|
+
// 현재는 `match`와 `range`만 지원합니다.
|
|
340
|
+
|
|
341
|
+
return false; // 지원하지 않는 조건 타입
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
#filter = async (filter) => {
|
|
345
|
+
console.log("===============================");
|
|
346
|
+
console.log(filter);
|
|
347
|
+
|
|
348
|
+
const result1 = this.#filterJsonArray(this.#getData(), filter);
|
|
349
|
+
console.log(result1);
|
|
350
|
+
};
|
|
351
|
+
|
|
235
352
|
#q1 = async () => {
|
|
236
353
|
const filter = await this.#generateQdrantFilter();
|
|
237
|
-
return await this.#
|
|
354
|
+
return await this.#filter(filter);
|
|
238
355
|
};
|
|
239
356
|
|
|
240
357
|
#q2 = async () => {
|
|
@@ -307,10 +424,6 @@ class aiContainer extends HTMLElement
|
|
|
307
424
|
}
|
|
308
425
|
};
|
|
309
426
|
|
|
310
|
-
#q3 = async () => {
|
|
311
|
-
const filter = await this.#generateQdrantFilter();
|
|
312
|
-
return await this.#searchWithQdrantFilter(filter);
|
|
313
|
-
};
|
|
314
427
|
|
|
315
428
|
#init = (info) => {
|
|
316
429
|
|
|
@@ -362,7 +475,7 @@ class aiContainer extends HTMLElement
|
|
|
362
475
|
await this.#q2();
|
|
363
476
|
}
|
|
364
477
|
else {
|
|
365
|
-
await this.#
|
|
478
|
+
await this.#q2();
|
|
366
479
|
}
|
|
367
480
|
} catch (error) {
|
|
368
481
|
//console.error("Error generating Qdrant filter:", error);
|
package/dist/bundle.cjs.js
CHANGED
|
@@ -54142,9 +54142,8 @@ class aiContainer extends HTMLElement
|
|
|
54142
54142
|
</div>
|
|
54143
54143
|
<div class="menu">
|
|
54144
54144
|
<div class="collapse-icon"></div>
|
|
54145
|
-
<div class="menu-icon menu-filter"></div>
|
|
54146
|
-
<div class="menu-icon menu-general
|
|
54147
|
-
<div class="menu-icon menu-db"></div>
|
|
54145
|
+
<div class="menu-icon menu-filter" active></div>
|
|
54146
|
+
<div class="menu-icon menu-general"></div>
|
|
54148
54147
|
<div class="menu-icon menu-setting"></div>
|
|
54149
54148
|
</div>
|
|
54150
54149
|
</div>
|
|
@@ -54210,6 +54209,12 @@ class aiContainer extends HTMLElement
|
|
|
54210
54209
|
}
|
|
54211
54210
|
};
|
|
54212
54211
|
|
|
54212
|
+
#getData = () => {
|
|
54213
|
+
if (this.#target.tagName === "NINE-GRID") {
|
|
54214
|
+
return this.#target.data.get();
|
|
54215
|
+
}
|
|
54216
|
+
};
|
|
54217
|
+
|
|
54213
54218
|
|
|
54214
54219
|
#generateQdrantFilter = async () => {
|
|
54215
54220
|
|
|
@@ -54320,11 +54325,118 @@ class aiContainer extends HTMLElement
|
|
|
54320
54325
|
|
|
54321
54326
|
return await this.#qdrantClient.search(collectionName, searchParams);
|
|
54322
54327
|
//}
|
|
54328
|
+
};
|
|
54329
|
+
|
|
54330
|
+
/**
|
|
54331
|
+
* Qdrant 필터링 조건에 따라 JSON 배열을 필터링하는 함수입니다.
|
|
54332
|
+
*
|
|
54333
|
+
* @param {Array<Object>} jsonArray 필터링할 JSON 객체 배열입니다.
|
|
54334
|
+
* @param {Object} filter 필터링 조건 객체입니다. Qdrant 필터와 유사한 구조를 가집니다.
|
|
54335
|
+
* 예시:
|
|
54336
|
+
* {
|
|
54337
|
+
* must: [ // 모든 조건이 참이어야 함
|
|
54338
|
+
* { key: "field1", match: { value: "some_value" } },
|
|
54339
|
+
* { key: "field2", range: { gte: 10, lt: 20 } }
|
|
54340
|
+
* ],
|
|
54341
|
+
* should: [ // 하나 이상의 조건이 참이어야 함
|
|
54342
|
+
* { key: "field3", match: { value: "another_value" } },
|
|
54343
|
+
* { key: "field4", match: { any: ["valueA", "valueB"] } }
|
|
54344
|
+
* ],
|
|
54345
|
+
* must_not: [ // 어떤 조건도 참이 아니어야 함
|
|
54346
|
+
* { key: "field5", match: { value: "excluded_value" } }
|
|
54347
|
+
* ]
|
|
54348
|
+
* }
|
|
54349
|
+
* @returns {Array<Object>} 필터링된 JSON 객체 배열입니다.
|
|
54350
|
+
*/
|
|
54351
|
+
#filterJsonArray = (jsonArray, filter) => {
|
|
54352
|
+
if (!jsonArray || !Array.isArray(jsonArray)) {
|
|
54353
|
+
console.error("첫 번째 인수는 JSON 배열이어야 합니다.");
|
|
54354
|
+
return [];
|
|
54355
|
+
}
|
|
54356
|
+
if (!filter || typeof filter !== 'object') {
|
|
54357
|
+
// 필터 조건이 없거나 유효하지 않으면 원본 배열 반환
|
|
54358
|
+
return jsonArray;
|
|
54359
|
+
}
|
|
54360
|
+
|
|
54361
|
+
return jsonArray.filter(item => {
|
|
54362
|
+
// 'must' 조건 처리: 모든 'must' 조건이 참이어야 합니다.
|
|
54363
|
+
if (filter.must && !filter.must.every(condition => this.#evaluateCondition(item, condition))) {
|
|
54364
|
+
return false;
|
|
54365
|
+
}
|
|
54366
|
+
|
|
54367
|
+
// 'should' 조건 처리: 하나 이상의 'should' 조건이 참이어야 합니다.
|
|
54368
|
+
// 'should' 조건이 없으면 이 부분은 건너뜁니다.
|
|
54369
|
+
if (filter.should && filter.should.length > 0 && !filter.should.some(condition => this.#evaluateCondition(item, condition))) {
|
|
54370
|
+
return false;
|
|
54371
|
+
} else if (filter.should && filter.should.length === 0 && (filter.must || filter.must_not)) ;
|
|
54372
|
+
|
|
54373
|
+
|
|
54374
|
+
// 'must_not' 조건 처리: 어떤 'must_not' 조건도 참이 아니어야 합니다.
|
|
54375
|
+
if (filter.must_not && filter.must_not.some(condition => this.#evaluateCondition(item, condition))) {
|
|
54376
|
+
return false;
|
|
54377
|
+
}
|
|
54378
|
+
|
|
54379
|
+
return true;
|
|
54380
|
+
});
|
|
54323
54381
|
}
|
|
54324
54382
|
|
|
54383
|
+
/**
|
|
54384
|
+
* 단일 필터링 조건을 평가하는 헬퍼 함수입니다.
|
|
54385
|
+
* @param {Object} item 현재 평가 중인 JSON 객체입니다.
|
|
54386
|
+
* @param {Object} condition 평가할 단일 조건입니다. (예: { key: "field1", match: { value: "some_value" } })
|
|
54387
|
+
* @returns {boolean} 조건이 참이면 true, 그렇지 않으면 false.
|
|
54388
|
+
*/
|
|
54389
|
+
#evaluateCondition = (item, condition) => {
|
|
54390
|
+
const valueInItem = item[condition.key];
|
|
54391
|
+
|
|
54392
|
+
if (condition.match) {
|
|
54393
|
+
const match = condition.match;
|
|
54394
|
+
if (match.value !== undefined) {
|
|
54395
|
+
return valueInItem === match.value;
|
|
54396
|
+
}
|
|
54397
|
+
if (match.any && Array.isArray(match.any)) {
|
|
54398
|
+
return match.any.includes(valueInItem);
|
|
54399
|
+
}
|
|
54400
|
+
if (match.all && Array.isArray(match.all)) {
|
|
54401
|
+
// item[condition.key]가 배열이라고 가정
|
|
54402
|
+
if (!Array.isArray(valueInItem)) return false;
|
|
54403
|
+
return match.all.every(val => valueInItem.includes(val));
|
|
54404
|
+
}
|
|
54405
|
+
if (match.text !== undefined) {
|
|
54406
|
+
// 텍스트 매치는 부분 문자열 일치 또는 정규식 등으로 확장 가능
|
|
54407
|
+
// 여기서는 단순 포함 여부로 구현
|
|
54408
|
+
return typeof valueInItem === 'string' && valueInItem.includes(match.text);
|
|
54409
|
+
}
|
|
54410
|
+
}
|
|
54411
|
+
|
|
54412
|
+
if (condition.range) {
|
|
54413
|
+
const range = condition.range;
|
|
54414
|
+
if (typeof valueInItem !== 'number') return false; // 숫자가 아니면 범위 비교 불가
|
|
54415
|
+
|
|
54416
|
+
if (range.gte !== undefined && !(valueInItem >= range.gte)) return false;
|
|
54417
|
+
if (range.gt !== undefined && !(valueInItem > range.gt)) return false;
|
|
54418
|
+
if (range.lte !== undefined && !(valueInItem <= range.lte)) return false;
|
|
54419
|
+
if (range.lt !== undefined && !(valueInItem < range.lt)) return false;
|
|
54420
|
+
return true;
|
|
54421
|
+
}
|
|
54422
|
+
|
|
54423
|
+
// 다른 필터 타입 (예: `geo_bounding_box`, `has_id` 등)은 필요에 따라 추가 구현
|
|
54424
|
+
// 현재는 `match`와 `range`만 지원합니다.
|
|
54425
|
+
|
|
54426
|
+
return false; // 지원하지 않는 조건 타입
|
|
54427
|
+
}
|
|
54428
|
+
|
|
54429
|
+
#filter = async (filter) => {
|
|
54430
|
+
console.log("===============================");
|
|
54431
|
+
console.log(filter);
|
|
54432
|
+
|
|
54433
|
+
const result1 = this.#filterJsonArray(this.#getData(), filter);
|
|
54434
|
+
console.log(result1);
|
|
54435
|
+
};
|
|
54436
|
+
|
|
54325
54437
|
#q1 = async () => {
|
|
54326
54438
|
const filter = await this.#generateQdrantFilter();
|
|
54327
|
-
return await this.#
|
|
54439
|
+
return await this.#filter(filter);
|
|
54328
54440
|
};
|
|
54329
54441
|
|
|
54330
54442
|
#q2 = async () => {
|
|
@@ -54377,10 +54489,6 @@ class aiContainer extends HTMLElement
|
|
|
54377
54489
|
}
|
|
54378
54490
|
};
|
|
54379
54491
|
|
|
54380
|
-
#q3 = async () => {
|
|
54381
|
-
const filter = await this.#generateQdrantFilter();
|
|
54382
|
-
return await this.#searchWithQdrantFilter(filter);
|
|
54383
|
-
};
|
|
54384
54492
|
|
|
54385
54493
|
#init = (info) => {
|
|
54386
54494
|
|
|
@@ -54431,7 +54539,7 @@ class aiContainer extends HTMLElement
|
|
|
54431
54539
|
await this.#q2();
|
|
54432
54540
|
}
|
|
54433
54541
|
else {
|
|
54434
|
-
await this.#
|
|
54542
|
+
await this.#q2();
|
|
54435
54543
|
}
|
|
54436
54544
|
} catch (error) {
|
|
54437
54545
|
//console.error("Error generating Qdrant filter:", error);
|
package/dist/bundle.esm.js
CHANGED
|
@@ -54140,9 +54140,8 @@ class aiContainer extends HTMLElement
|
|
|
54140
54140
|
</div>
|
|
54141
54141
|
<div class="menu">
|
|
54142
54142
|
<div class="collapse-icon"></div>
|
|
54143
|
-
<div class="menu-icon menu-filter"></div>
|
|
54144
|
-
<div class="menu-icon menu-general
|
|
54145
|
-
<div class="menu-icon menu-db"></div>
|
|
54143
|
+
<div class="menu-icon menu-filter" active></div>
|
|
54144
|
+
<div class="menu-icon menu-general"></div>
|
|
54146
54145
|
<div class="menu-icon menu-setting"></div>
|
|
54147
54146
|
</div>
|
|
54148
54147
|
</div>
|
|
@@ -54208,6 +54207,12 @@ class aiContainer extends HTMLElement
|
|
|
54208
54207
|
}
|
|
54209
54208
|
};
|
|
54210
54209
|
|
|
54210
|
+
#getData = () => {
|
|
54211
|
+
if (this.#target.tagName === "NINE-GRID") {
|
|
54212
|
+
return this.#target.data.get();
|
|
54213
|
+
}
|
|
54214
|
+
};
|
|
54215
|
+
|
|
54211
54216
|
|
|
54212
54217
|
#generateQdrantFilter = async () => {
|
|
54213
54218
|
|
|
@@ -54318,11 +54323,118 @@ class aiContainer extends HTMLElement
|
|
|
54318
54323
|
|
|
54319
54324
|
return await this.#qdrantClient.search(collectionName, searchParams);
|
|
54320
54325
|
//}
|
|
54326
|
+
};
|
|
54327
|
+
|
|
54328
|
+
/**
|
|
54329
|
+
* Qdrant 필터링 조건에 따라 JSON 배열을 필터링하는 함수입니다.
|
|
54330
|
+
*
|
|
54331
|
+
* @param {Array<Object>} jsonArray 필터링할 JSON 객체 배열입니다.
|
|
54332
|
+
* @param {Object} filter 필터링 조건 객체입니다. Qdrant 필터와 유사한 구조를 가집니다.
|
|
54333
|
+
* 예시:
|
|
54334
|
+
* {
|
|
54335
|
+
* must: [ // 모든 조건이 참이어야 함
|
|
54336
|
+
* { key: "field1", match: { value: "some_value" } },
|
|
54337
|
+
* { key: "field2", range: { gte: 10, lt: 20 } }
|
|
54338
|
+
* ],
|
|
54339
|
+
* should: [ // 하나 이상의 조건이 참이어야 함
|
|
54340
|
+
* { key: "field3", match: { value: "another_value" } },
|
|
54341
|
+
* { key: "field4", match: { any: ["valueA", "valueB"] } }
|
|
54342
|
+
* ],
|
|
54343
|
+
* must_not: [ // 어떤 조건도 참이 아니어야 함
|
|
54344
|
+
* { key: "field5", match: { value: "excluded_value" } }
|
|
54345
|
+
* ]
|
|
54346
|
+
* }
|
|
54347
|
+
* @returns {Array<Object>} 필터링된 JSON 객체 배열입니다.
|
|
54348
|
+
*/
|
|
54349
|
+
#filterJsonArray = (jsonArray, filter) => {
|
|
54350
|
+
if (!jsonArray || !Array.isArray(jsonArray)) {
|
|
54351
|
+
console.error("첫 번째 인수는 JSON 배열이어야 합니다.");
|
|
54352
|
+
return [];
|
|
54353
|
+
}
|
|
54354
|
+
if (!filter || typeof filter !== 'object') {
|
|
54355
|
+
// 필터 조건이 없거나 유효하지 않으면 원본 배열 반환
|
|
54356
|
+
return jsonArray;
|
|
54357
|
+
}
|
|
54358
|
+
|
|
54359
|
+
return jsonArray.filter(item => {
|
|
54360
|
+
// 'must' 조건 처리: 모든 'must' 조건이 참이어야 합니다.
|
|
54361
|
+
if (filter.must && !filter.must.every(condition => this.#evaluateCondition(item, condition))) {
|
|
54362
|
+
return false;
|
|
54363
|
+
}
|
|
54364
|
+
|
|
54365
|
+
// 'should' 조건 처리: 하나 이상의 'should' 조건이 참이어야 합니다.
|
|
54366
|
+
// 'should' 조건이 없으면 이 부분은 건너뜁니다.
|
|
54367
|
+
if (filter.should && filter.should.length > 0 && !filter.should.some(condition => this.#evaluateCondition(item, condition))) {
|
|
54368
|
+
return false;
|
|
54369
|
+
} else if (filter.should && filter.should.length === 0 && (filter.must || filter.must_not)) ;
|
|
54370
|
+
|
|
54371
|
+
|
|
54372
|
+
// 'must_not' 조건 처리: 어떤 'must_not' 조건도 참이 아니어야 합니다.
|
|
54373
|
+
if (filter.must_not && filter.must_not.some(condition => this.#evaluateCondition(item, condition))) {
|
|
54374
|
+
return false;
|
|
54375
|
+
}
|
|
54376
|
+
|
|
54377
|
+
return true;
|
|
54378
|
+
});
|
|
54321
54379
|
}
|
|
54322
54380
|
|
|
54381
|
+
/**
|
|
54382
|
+
* 단일 필터링 조건을 평가하는 헬퍼 함수입니다.
|
|
54383
|
+
* @param {Object} item 현재 평가 중인 JSON 객체입니다.
|
|
54384
|
+
* @param {Object} condition 평가할 단일 조건입니다. (예: { key: "field1", match: { value: "some_value" } })
|
|
54385
|
+
* @returns {boolean} 조건이 참이면 true, 그렇지 않으면 false.
|
|
54386
|
+
*/
|
|
54387
|
+
#evaluateCondition = (item, condition) => {
|
|
54388
|
+
const valueInItem = item[condition.key];
|
|
54389
|
+
|
|
54390
|
+
if (condition.match) {
|
|
54391
|
+
const match = condition.match;
|
|
54392
|
+
if (match.value !== undefined) {
|
|
54393
|
+
return valueInItem === match.value;
|
|
54394
|
+
}
|
|
54395
|
+
if (match.any && Array.isArray(match.any)) {
|
|
54396
|
+
return match.any.includes(valueInItem);
|
|
54397
|
+
}
|
|
54398
|
+
if (match.all && Array.isArray(match.all)) {
|
|
54399
|
+
// item[condition.key]가 배열이라고 가정
|
|
54400
|
+
if (!Array.isArray(valueInItem)) return false;
|
|
54401
|
+
return match.all.every(val => valueInItem.includes(val));
|
|
54402
|
+
}
|
|
54403
|
+
if (match.text !== undefined) {
|
|
54404
|
+
// 텍스트 매치는 부분 문자열 일치 또는 정규식 등으로 확장 가능
|
|
54405
|
+
// 여기서는 단순 포함 여부로 구현
|
|
54406
|
+
return typeof valueInItem === 'string' && valueInItem.includes(match.text);
|
|
54407
|
+
}
|
|
54408
|
+
}
|
|
54409
|
+
|
|
54410
|
+
if (condition.range) {
|
|
54411
|
+
const range = condition.range;
|
|
54412
|
+
if (typeof valueInItem !== 'number') return false; // 숫자가 아니면 범위 비교 불가
|
|
54413
|
+
|
|
54414
|
+
if (range.gte !== undefined && !(valueInItem >= range.gte)) return false;
|
|
54415
|
+
if (range.gt !== undefined && !(valueInItem > range.gt)) return false;
|
|
54416
|
+
if (range.lte !== undefined && !(valueInItem <= range.lte)) return false;
|
|
54417
|
+
if (range.lt !== undefined && !(valueInItem < range.lt)) return false;
|
|
54418
|
+
return true;
|
|
54419
|
+
}
|
|
54420
|
+
|
|
54421
|
+
// 다른 필터 타입 (예: `geo_bounding_box`, `has_id` 등)은 필요에 따라 추가 구현
|
|
54422
|
+
// 현재는 `match`와 `range`만 지원합니다.
|
|
54423
|
+
|
|
54424
|
+
return false; // 지원하지 않는 조건 타입
|
|
54425
|
+
}
|
|
54426
|
+
|
|
54427
|
+
#filter = async (filter) => {
|
|
54428
|
+
console.log("===============================");
|
|
54429
|
+
console.log(filter);
|
|
54430
|
+
|
|
54431
|
+
const result1 = this.#filterJsonArray(this.#getData(), filter);
|
|
54432
|
+
console.log(result1);
|
|
54433
|
+
};
|
|
54434
|
+
|
|
54323
54435
|
#q1 = async () => {
|
|
54324
54436
|
const filter = await this.#generateQdrantFilter();
|
|
54325
|
-
return await this.#
|
|
54437
|
+
return await this.#filter(filter);
|
|
54326
54438
|
};
|
|
54327
54439
|
|
|
54328
54440
|
#q2 = async () => {
|
|
@@ -54375,10 +54487,6 @@ class aiContainer extends HTMLElement
|
|
|
54375
54487
|
}
|
|
54376
54488
|
};
|
|
54377
54489
|
|
|
54378
|
-
#q3 = async () => {
|
|
54379
|
-
const filter = await this.#generateQdrantFilter();
|
|
54380
|
-
return await this.#searchWithQdrantFilter(filter);
|
|
54381
|
-
};
|
|
54382
54490
|
|
|
54383
54491
|
#init = (info) => {
|
|
54384
54492
|
|
|
@@ -54429,7 +54537,7 @@ class aiContainer extends HTMLElement
|
|
|
54429
54537
|
await this.#q2();
|
|
54430
54538
|
}
|
|
54431
54539
|
else {
|
|
54432
|
-
await this.#
|
|
54540
|
+
await this.#q2();
|
|
54433
54541
|
}
|
|
54434
54542
|
} catch (error) {
|
|
54435
54543
|
//console.error("Error generating Qdrant filter:", error);
|
package/package.json
CHANGED
package/src/ai/aiContainer.js
CHANGED
|
@@ -48,9 +48,8 @@ class aiContainer extends HTMLElement
|
|
|
48
48
|
</div>
|
|
49
49
|
<div class="menu">
|
|
50
50
|
<div class="collapse-icon"></div>
|
|
51
|
-
<div class="menu-icon menu-filter"></div>
|
|
52
|
-
<div class="menu-icon menu-general
|
|
53
|
-
<div class="menu-icon menu-db"></div>
|
|
51
|
+
<div class="menu-icon menu-filter" active></div>
|
|
52
|
+
<div class="menu-icon menu-general"></div>
|
|
54
53
|
<div class="menu-icon menu-setting"></div>
|
|
55
54
|
</div>
|
|
56
55
|
</div>
|
|
@@ -116,6 +115,12 @@ class aiContainer extends HTMLElement
|
|
|
116
115
|
}
|
|
117
116
|
};
|
|
118
117
|
|
|
118
|
+
#getData = () => {
|
|
119
|
+
if (this.#target.tagName === "NINE-GRID") {
|
|
120
|
+
return this.#target.data.get();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
119
124
|
|
|
120
125
|
#generateQdrantFilter = async () => {
|
|
121
126
|
|
|
@@ -230,11 +235,123 @@ class aiContainer extends HTMLElement
|
|
|
230
235
|
// console.error("Error during Qdrant search:", error);
|
|
231
236
|
return [];
|
|
232
237
|
//}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Qdrant 필터링 조건에 따라 JSON 배열을 필터링하는 함수입니다.
|
|
242
|
+
*
|
|
243
|
+
* @param {Array<Object>} jsonArray 필터링할 JSON 객체 배열입니다.
|
|
244
|
+
* @param {Object} filter 필터링 조건 객체입니다. Qdrant 필터와 유사한 구조를 가집니다.
|
|
245
|
+
* 예시:
|
|
246
|
+
* {
|
|
247
|
+
* must: [ // 모든 조건이 참이어야 함
|
|
248
|
+
* { key: "field1", match: { value: "some_value" } },
|
|
249
|
+
* { key: "field2", range: { gte: 10, lt: 20 } }
|
|
250
|
+
* ],
|
|
251
|
+
* should: [ // 하나 이상의 조건이 참이어야 함
|
|
252
|
+
* { key: "field3", match: { value: "another_value" } },
|
|
253
|
+
* { key: "field4", match: { any: ["valueA", "valueB"] } }
|
|
254
|
+
* ],
|
|
255
|
+
* must_not: [ // 어떤 조건도 참이 아니어야 함
|
|
256
|
+
* { key: "field5", match: { value: "excluded_value" } }
|
|
257
|
+
* ]
|
|
258
|
+
* }
|
|
259
|
+
* @returns {Array<Object>} 필터링된 JSON 객체 배열입니다.
|
|
260
|
+
*/
|
|
261
|
+
#filterJsonArray = (jsonArray, filter) => {
|
|
262
|
+
if (!jsonArray || !Array.isArray(jsonArray)) {
|
|
263
|
+
console.error("첫 번째 인수는 JSON 배열이어야 합니다.");
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
if (!filter || typeof filter !== 'object') {
|
|
267
|
+
// 필터 조건이 없거나 유효하지 않으면 원본 배열 반환
|
|
268
|
+
return jsonArray;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return jsonArray.filter(item => {
|
|
272
|
+
// 'must' 조건 처리: 모든 'must' 조건이 참이어야 합니다.
|
|
273
|
+
if (filter.must && !filter.must.every(condition => this.#evaluateCondition(item, condition))) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// 'should' 조건 처리: 하나 이상의 'should' 조건이 참이어야 합니다.
|
|
278
|
+
// 'should' 조건이 없으면 이 부분은 건너뜁니다.
|
|
279
|
+
if (filter.should && filter.should.length > 0 && !filter.should.some(condition => this.#evaluateCondition(item, condition))) {
|
|
280
|
+
return false;
|
|
281
|
+
} else if (filter.should && filter.should.length === 0 && (filter.must || filter.must_not)) {
|
|
282
|
+
// 'should'가 비어있고 'must'나 'must_not'가 있으면 'should'는 필터링에 영향 없음.
|
|
283
|
+
// 하지만 'should'만 있고 비어있다면, 사실상 필터링이 안 되는 것과 같으므로 true 반환.
|
|
284
|
+
// 이 로직은 Qdrant의 'should'가 비어있을 때의 동작과 일치하도록 조정될 수 있습니다.
|
|
285
|
+
// 현재는 'should'가 비어있으면 필터링에 영향이 없도록 합니다.
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
// 'must_not' 조건 처리: 어떤 'must_not' 조건도 참이 아니어야 합니다.
|
|
290
|
+
if (filter.must_not && filter.must_not.some(condition => this.#evaluateCondition(item, condition))) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return true;
|
|
295
|
+
});
|
|
233
296
|
}
|
|
234
297
|
|
|
298
|
+
/**
|
|
299
|
+
* 단일 필터링 조건을 평가하는 헬퍼 함수입니다.
|
|
300
|
+
* @param {Object} item 현재 평가 중인 JSON 객체입니다.
|
|
301
|
+
* @param {Object} condition 평가할 단일 조건입니다. (예: { key: "field1", match: { value: "some_value" } })
|
|
302
|
+
* @returns {boolean} 조건이 참이면 true, 그렇지 않으면 false.
|
|
303
|
+
*/
|
|
304
|
+
#evaluateCondition = (item, condition) => {
|
|
305
|
+
const valueInItem = item[condition.key];
|
|
306
|
+
|
|
307
|
+
if (condition.match) {
|
|
308
|
+
const match = condition.match;
|
|
309
|
+
if (match.value !== undefined) {
|
|
310
|
+
return valueInItem === match.value;
|
|
311
|
+
}
|
|
312
|
+
if (match.any && Array.isArray(match.any)) {
|
|
313
|
+
return match.any.includes(valueInItem);
|
|
314
|
+
}
|
|
315
|
+
if (match.all && Array.isArray(match.all)) {
|
|
316
|
+
// item[condition.key]가 배열이라고 가정
|
|
317
|
+
if (!Array.isArray(valueInItem)) return false;
|
|
318
|
+
return match.all.every(val => valueInItem.includes(val));
|
|
319
|
+
}
|
|
320
|
+
if (match.text !== undefined) {
|
|
321
|
+
// 텍스트 매치는 부분 문자열 일치 또는 정규식 등으로 확장 가능
|
|
322
|
+
// 여기서는 단순 포함 여부로 구현
|
|
323
|
+
return typeof valueInItem === 'string' && valueInItem.includes(match.text);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (condition.range) {
|
|
328
|
+
const range = condition.range;
|
|
329
|
+
if (typeof valueInItem !== 'number') return false; // 숫자가 아니면 범위 비교 불가
|
|
330
|
+
|
|
331
|
+
if (range.gte !== undefined && !(valueInItem >= range.gte)) return false;
|
|
332
|
+
if (range.gt !== undefined && !(valueInItem > range.gt)) return false;
|
|
333
|
+
if (range.lte !== undefined && !(valueInItem <= range.lte)) return false;
|
|
334
|
+
if (range.lt !== undefined && !(valueInItem < range.lt)) return false;
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// 다른 필터 타입 (예: `geo_bounding_box`, `has_id` 등)은 필요에 따라 추가 구현
|
|
339
|
+
// 현재는 `match`와 `range`만 지원합니다.
|
|
340
|
+
|
|
341
|
+
return false; // 지원하지 않는 조건 타입
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
#filter = async (filter) => {
|
|
345
|
+
console.log("===============================");
|
|
346
|
+
console.log(filter);
|
|
347
|
+
|
|
348
|
+
const result1 = this.#filterJsonArray(this.#getData(), filter);
|
|
349
|
+
console.log(result1);
|
|
350
|
+
};
|
|
351
|
+
|
|
235
352
|
#q1 = async () => {
|
|
236
353
|
const filter = await this.#generateQdrantFilter();
|
|
237
|
-
return await this.#
|
|
354
|
+
return await this.#filter(filter);
|
|
238
355
|
};
|
|
239
356
|
|
|
240
357
|
#q2 = async () => {
|
|
@@ -307,10 +424,6 @@ class aiContainer extends HTMLElement
|
|
|
307
424
|
}
|
|
308
425
|
};
|
|
309
426
|
|
|
310
|
-
#q3 = async () => {
|
|
311
|
-
const filter = await this.#generateQdrantFilter();
|
|
312
|
-
return await this.#searchWithQdrantFilter(filter);
|
|
313
|
-
};
|
|
314
427
|
|
|
315
428
|
#init = (info) => {
|
|
316
429
|
|
|
@@ -362,7 +475,7 @@ class aiContainer extends HTMLElement
|
|
|
362
475
|
await this.#q2();
|
|
363
476
|
}
|
|
364
477
|
else {
|
|
365
|
-
await this.#
|
|
478
|
+
await this.#q2();
|
|
366
479
|
}
|
|
367
480
|
} catch (error) {
|
|
368
481
|
//console.error("Error generating Qdrant filter:", error);
|