【问题标题】:compound index/searching on child array复合索引/搜索子数组
【发布时间】:2014-07-22 20:28:42
【问题描述】:

根据下面的数据,我正在寻找类似“找到父对象名称为'Panel'的块1”

所以,我尝试像这样设置复合索引:

objStore.createIndex('by_name_and_block', ['Name', 'blocks.Name']);

然后像这样调用它(有点):

var index = objStore.index("by_name_and_block");

var request = index.get("Panel", "1");

// I've also tried:
// var request = index.get(["Panel","1"]);
...

但这不起作用。有没有办法在 indexeddb 中设置这个复合索引?

样本数据:

[
    {
        Name: "Post",
        blocks: [
            {
                Name:"1",
                Arrays:[]
            },
            {
                Name:"2",
                Arrays:[]
            },
        ]
    },
    {
        Name: "Panel",
        blocks: [
            {
                Name:"1",
                Arrays:[]
            },
            {
                Name:"2",
                Arrays:[]
            },
        ]
    },
]

【问题讨论】:

  • 好点,我正在按照您在第一个示例中所说的那样做,但这是有道理的,这是行不通的。我把它切换到第二个例子,现在我得到DataError
  • 你的问题我不清楚。
  • 我怎样才能帮助更清楚@OrtomalaLokni?例如,我想获得一个对象,例如block.Name = "2" 和父对象Name = "Panel"——在上面的示例中,我将获得第二个父对象的第二个块对象。在 SQL 中,SELECT * FROM Parent JOIN Blocks <<on some criteria>> WHERE parent.Name = 'Panel' and blocks.Name = '1'
  • 我一直在看这个,我认为 keypath 的第二部分的定义是不正确的。根据显示的数据模型,“块”是一个数组。为了寻址该数组中的项目,您需要指定一个向量。例如:blocks[0].Name。这似乎不是您真正想要的,因此可能需要重新审视数据存储设计。

标签: javascript indexeddb nosql


【解决方案1】:

您的数据无法使用当前规范进行索引。见steps for extracting key from keyPath。请注意,对象不是数组键路径中的有效键值。

在 v2 中,您将能够使用索引函数表达式。

目前,您必须在持久化到数据库之前生成额外的变量,并在检索后将其删除。使用没有复合索引的 multiEntry 索引。

【讨论】:

    【解决方案2】:

    这个脚本是你想要的吗?

    var obj = [
        {
            Name: "Post",
            blocks: [
                {
                    Name:"1",
                    Arrays:[]
                },
                {
                    Name:"2",
                    Arrays:[]
                },
            ]
        },
        {
            Name: "Panel",
            blocks: [
                {
                    Name:"1",
                    Arrays:[]
                },
                {
                    Name:"2",
                    Arrays:[]
                },
            ]
        },
    ];
    
    function getBlockByName(objName, index){
        for(var i = 0; i < obj.length; i++){
            if(obj[i].Name == objName)
                return obj[i].blocks[index];
        }
    
        return false;
    }
    
    //Index starting from 0
    console.log(getBlockByName("Panel", 1));
    //Will return {Name:"2", Arrays:[]} object
    

    【讨论】:

    • 嗯,不是真的。我希望用 IndexedDb 来做这件事——那个 obj 实际上是一个 huge 对象,所以仅仅将它保存在内存中并通过它进行游标是行不通的。
    猜你喜欢
    • 1970-01-01
    • 2014-07-11
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    相关资源
    最近更新 更多