如何通过遍历 LIST 从 Aerospike 获取记录

我有数据库结构,接近于此:


+--------------+---------+------------------------------+

| hostname     |   cont  |         numbers              |

+--------------+---------+------------------------------+

|   host01     |{"k":"v"}|LIST(`[["1", "123456", ...]]`)|

|   host02     |{"k":"v"}|LIST(`[["1", "654321", ...]]`)|

+--------------+---------+------------------------------+

我想通过过滤垃圾箱“数字”和“主机名”来获得某些记录。它应该包含一个具有特定数字的字符串,这是我从其他组件获得的。在上面的代码中,它是“123456”


基本上,我以前都是这样搜索的,直到需要二维数组:


stmt := aerospike.NewStatement(namespaceName, setName)

stmt.SetPredExp(

 aerospike.NewPredExpStringBin("hostname"),

            aerospike.NewPredExpStringValue(inputHostName),

            aerospike.NewPredExpStringRegex(0),

            aerospike.NewPredExpStringBin("deleted"),

            aerospike.NewPredExpStringValue("true"),

            aerospike.NewPredExpStringEqual(),

            aerospike.NewPredExpNot(),

            aerospike.NewPredExpAnd(2))

)

我一直在寻找通过数组过滤的可能方法,但没有得到任何解决方案。


我在网上找到的方式是这样的:


stmt := aerospike.NewStatement("test", "settest")

qPolicy := aerospike.NewQueryPolicy()

qPolicy.PredExp = append(qPolicy.PredExp,

            aerospike.NewPredExpStringVar("v"),

            aerospike.NewPredExpStringValue(id),

            aerospike.NewPredExpStringEqual(),

            aerospike.NewPredExpListBin("numbers"),

            aerospike.NewPredExpListIterateOr("v"))

recordSet, err := aerospikeClient.client.Query(qPolicy, stmt)

但它不起作用。


如果我使用主机名和某种方式解析数组来提供谓词表达式,是否可以搜索记录?


更新:


我发现,这种情况可以通过使用过滤器表达式来解决,尤其是使用 CDTContext。但是 Aerospike 文档中关于此工具的使用信息非常少,尤其是关于 Go 代码的信息。我只找到了这种方法,它可以提供帮助,但我不明白如何在我的情况下正确使用它:


func aerospike.ExpListGetByValue(returnType aerospike.ListReturnType, value *aerospike.Expression, bin *aerospike.Expression, ctx ...*aerospike.CDTContext) *aerospike.Expression

UPD2 通过使用 ExpListGetByValue 我试图进行查询,但它找不到任何东西。它看起来像这样:


stmt := aerospike.NewStatement(namespaceName, setName)

qPolicy := aerospike.NewQueryPolicy()

qPolicy.FilterExpression = aerospike.ExpEq(

aerospike.ExpListGetByValue(


这recordSet是空的,虽然“数字”箱确实包含这个numVal




小怪兽爱吃肉
浏览 80回答 1
1回答

隔江千里

我正在使用您在第二次更新中创建的新的和修改过的过滤器运行您的测试,它似乎有效。这是我使用的完整代码(基于 Git 存储库中的 Aerospike 示例目录):/* * Copyright 2014-2022 Aerospike, Inc. * * Portions may be licensed to Aerospike, Inc. under one or more contributor * license agreements. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */package mainimport (    "log"    as "github.com/aerospike/aerospike-client-go/v5"    shared "github.com/aerospike/aerospike-client-go/v5/examples/shared")func main() {    testListExp(shared.Client)    log.Println("Example finished successfully.")}func testListExp(client *as.Client) {    log.Printf("Test List Expression")    key, _ := as.NewKey(*shared.Namespace, *shared.Set, "mapkey1")    client.Delete(shared.WritePolicy, key)    binHostname := as.NewBin("hostname", "host01")    amap := map[string]string{        "k": "v",    }    list := []string{        "1",        "123456",        "1111",        "222",    }    binCont := as.NewBin("cont", amap)    binNumbers := as.NewBin("numbers", list)    client.PutBins(shared.WritePolicy, key, binHostname, binCont, binNumbers)    key, _ = as.NewKey(*shared.Namespace, *shared.Set, "mapkey2")    binHostname = as.NewBin("hostname", "host02")    list = []string{        "1",        "654321",        "2222",        "3333",    }    binNumbers = as.NewBin("numbers", list)    client.PutBins(shared.WritePolicy, key, binHostname, binCont, binNumbers)    // numbVal := "654321"    getPolicy := as.NewQueryPolicy()    getPolicy.FilterExpression =        as.ExpEq(            as.ExpListGetByValue(                as.ListReturnTypeCount,                as.ExpStringVal("654321"),                as.ExpListBin("numbers")),            as.ExpIntVal(1))    stmt := as.NewStatement(*shared.Namespace, *shared.Set)    recordSet, err := client.Query(getPolicy, stmt)    shared.PanicOnError(err)    for res := range recordSet.Results() {        log.Println(res.Record.Bins)    }}输出是:$ go run listExpression.go  -h 172.17.0.32022/06/08 12:00:19 hosts:              172.17.0.32022/06/08 12:00:19 port:               30002022/06/08 12:00:19 user:2022/06/08 12:00:19 password:           *2022/06/08 12:00:19 namespace:          test2022/06/08 12:00:19 set:                testset2022/06/08 12:00:19 Test List Expression2022/06/08 12:00:19 map[cont:map[k:v] hostname:host02 numbers:[1 654321 2222 3333]]2022/06/08 12:00:19 Example finished successfully.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go