gpt4 book ai didi

java - MongoDB 中的查询场景

转载 作者:太空宇宙 更新时间:2023-11-04 12:01:23 26 4
gpt4 key购买 nike

由于我是 mongoDB 的新手,我想知道以下问题:我的文档中有一个字段(让我们调用 fieldA )。该字段的值存储为数字表示形式的十六进制字符串。是否可以检索那些文档的子集 fieldA根据数字表示,值落在给定的值范围内?我假设该字段存储为字符串,mongoDB 会按字典顺序比较 fieldA根据给定的查询限制,什么会与我的需求不一致。

假设我的文档范围是:fieldA >= "0x12f"fieldA <= "0x12ea"在这种情况下,我假设 mongoDB 会按字典顺序比较来做出决定,但在这种情况下,我想根据数值进行比较。

最佳答案

在 MongoDB 中,如果将十六进制字符串转换为二进制数据,则可以对大于 64 位的十六进制执行范围查询。 Java 的 BigInteger 类允许这样做。

考虑以下代码以二进制形式插入和查询十六进制值

private static void bigIntTest(MongoCollection<Document> bigIntCollection) {
// BigInteger cannot parse 0x, so it must be stripped off
// the "16" argument represent base 16 radix
BigInteger floor = new BigInteger("0x12f".substring(2), 16);
BigInteger ceiling = new BigInteger("0x12ea".substring(2), 16);
BigInteger between = new BigInteger("0x555".substring(2), 16);
// The toByteArray() method on BigInteger returns a byte array
// Containing the two's-complement representation of this BigInteger.
// MongoDB will store the byte array as a binary data field
bigIntCollection.insertOne(new Document("value", floor.toByteArray()));
bigIntCollection.insertOne(new Document("value", between.toByteArray()));
bigIntCollection.insertOne(new Document("value", ceiling.toByteArray()));

rangeQuery(bigIntCollection, floor, ceiling);
// Test with values greater than Long.MAX_VALUE
BigInteger newFloor = new BigInteger("8000000000000000", 16);
BigInteger newBetween = new BigInteger("1dcd64ffffffffffe58250e3", 16);
BigInteger newCeiling = new BigInteger("4563918244f3fffff538dcfb7617ffff", 16);
List<Document> newDocuments = Arrays.asList(new Document[] { new Document("value", newFloor.toByteArray()),
new Document("value", newBetween.toByteArray()), new Document("value", newCeiling.toByteArray()) });
bigIntCollection.insertMany(newDocuments);
rangeQuery(bigIntCollection, newFloor, newCeiling);
}

private static void rangeQuery(MongoCollection<Document> bigIntCollection, BigInteger floor, BigInteger ceiling) {
Document range = new Document("$gt", floor.toByteArray());
range.append("$lt", ceiling.toByteArray());
Document filter = new Document("value", range);
FindIterable<Document> find = bigIntCollection.find().filter(filter);
find.iterator().forEachRemaining(new Consumer<Document>() {
@Override
public void accept(Document t) {
byte[] data = ((Binary) t.get("value")).getData();
System.out.println(new BigInteger(data).toString(16));
}
});
}

第二组十六进制值超过了Long.MAX_VALUE,但它仍然有效。然而,我建议在生产中使用此技术之前进行广泛的测试,特别是如果可能存在负数并且在溢出边界附近。完整代码可以找到 here

此解决方案附带一个附加警告。对于较大的二进制值,索引在内存和性能方面可能会变得昂贵。请务必查看有关此主题的 MongoDB docs

关于java - MongoDB 中的查询场景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40873736/

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