gpt4 book ai didi

javascript - IndexedDB - 计算值出现次数?

转载 作者:行者123 更新时间:2023-11-28 01:11:10 29 4
gpt4 key购买 nike

我正在为在线日语词典开发 Chrome 扩展,我正在尝试记录和显示用户的查询统计信息,以便他知道他最缺少哪些日语术语。

为此,我的目的是显示过去 X 天内查询最多的汉字(日语字符)。因此,我在扩展indexedDB中使用汉字/日期对和自动编号键创建了一个简单的对象存储,但似乎没有办法在indexedDB中执行这些查询?

这是使用游标并使用 JavaScript 回调按日期过滤和计算出现次数的唯一方法吗?

编辑:用于创建数据库的代码

const DB_NAME = "kioku"
const DB_VERSION = 1;
const KANJI_STORE = "kanji";

var db;
(function() {
var request = window.indexedDB.open(DB_NAME, DB_VERSION);
request.onupgradeneeded = function(e) {
db = e.target.result;
var kanjiStore = db.createObjectStore(KANJI_STORE, { autoIncrement: true });
kanjiStore.createIndex("date", "date", { unique: false });
}
})();

通过事件处理程序添加数据

function newRecentKanjiHandler(request, sender, sendResponse) {
/* ...stuff before this point was irrelevant so I removed it */

var kanjiStore = db.transaction([KANJI_STORE], "readwrite").objectStore(KANJI_STORE);
kanjiStore.add({kanji: request.kanji, date: Date.now()});
}

带有示例数据的屏幕截图

Screenshot with sample data

在这种情况下,我想显示类似的内容

x3: 杉
x2: 刀, 尻
x1: 刃

对于用户。在按日期范围过滤后,只是对出现次数进行简单的计数,在本例中我没有这样做,因为时间戳在一小时内,而我的目的是过滤最近几天或几周。

最佳答案

我喜欢这个问题。我确信有人会有比我更好的答案,但这是一个随机的尝试。

首先,我应该指出一点,您在尝试将 event.target.result 分配给数据库时会遇到问题。您正在尝试将仅在其范围内有效的对象插入外部范围。这只会给你以后带来麻烦。我建议更多地了解 JavaScript 中的异步函数。

其次,我首先从当前方向后退一步,回顾一下有关您要解决的问题的一些基本假设。有时indexedDB并不是最好的解决方案。不幸的是,使用indexedDB 迫使您尽早面对这些设计问题。

您需要存储每个关键事件吗?如果不是,那么问题的规模仅限于不同汉字键的数量,而不是事件的数量。您可以完全放弃使用indexedDB,而使用一个保存到本地存储的简单对象。

如果规模有点大,那么确定您存储事件是仅用于您的问题还是用于其他目的?如果这只是您自己问题的目的,请考虑更改您存储的内容(架构)以仅解决其特定目的,而不是未知的其他目的列表。

例如,如果只是为了这个目的,并且不需要扩展,那么您可以完全避免使用indexedDB,而只使用本地存储。类似于以下内容:

function onCharEvent(char) {
var obj = JSON.parse(localStorage.KANJI_STATS || '');
var bar = obj[char] || {char: char, count: 0};
bar.count++;
bar.lastObserved = Date.now();
obj[char] = bar;
localStorage.KANJI_STATS = JSON.stringify(obj);
}

如果该功能只是用于此目的,并且必须是大规模的,您可以简化架构。首先想象一下在完成所有分组、排序和计数后,查询的类似列表的结果应该是什么样子。然后考虑如何在该模式中执行添加和放置操作。如果我理解正确的话,您希望获得如下所示的结果集合:

Kanji char | Count | Last observed
----------------------------------
char1 | 1 | 1234123412345
char2 | 2 | 4643563456345
char3 | 3 | 3245234523452

每个实例(记录)都包含一个唯一的字符。计数代表观察该 Angular 色的次数。 Last-observed 属性表示最近观察该 Angular 色的时间。

// Setup or change the schema
function onUpgradeNeeded() {
var db = this.result;
var store = db.createObjectStore('kanji', {keyPath: kanjiChar});
store.createIndex('lastObserved','lastObserved');
}

function openDB(onOpen) {
var openRequest = indexedDB.open(DBNAME,DBVERSION);
openRequest.onupgradeneeded = onUpgradeNeeded;
openrequest.onsuccess = function() {
onOpen(this.result);
};
}

function onKeyEvent(event) {
var kanjiChar = event.target.value;
openDB(function(db) {
put(db, kanjiChar);
});
}

// Insert or update the kanji in the store
function put(db, kanjiChar, oncomplete) {
var tx = db.transaction('kanji','readwrite');
tx.oncomplete = function() {
oncomplete(kanjiChar);
};

var store = tx.objectStore('kanji');
store.openCursor(kanji).onsuccess = function() {
var cursor = this.result;
if(cursor) {
var obj = cursor.value;
obj.count = obj.count ? obj.count + 1 : 1;
obj.lastObserved = Date.now();
cursor.update(obj);
} else {
store.add({
kanjiChar: kanji,
count: 1,
lastObserved: Date.now()
});
}
};
}

function getStats(db, oncomplete) {
var tx = db.transaction('kanji');
var allStats = [];

tx.oncomplete = function() {
oncomplete(allStats);
};

var kanjiStore = tx.objectStore('kanji');
var lastObservedIndex = kanjiStore.index('lastObserved');
var LIMIT = 10;
var counter = 0;
lastObservedIndex.openCursor('prev').onsuccess = function() {
var cursor = this.result;
if(cursor) {
allStats.push(cursor.value);
if(counter++ < LIMIT) {
// Only continue
cursor.continue();
}
}
};
}

关于javascript - IndexedDB - 计算值出现次数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24416657/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com