NutzCN Logo
问答 mongodb 按id 查询返回错误
发布于 2678天前 作者 Rekoe 3034 次浏览 复制 上一个帖子 下一个帖子
标签:

RT
在命令行执行 是没问题的

db.user_push.update_time.find({"_id":"rekoe"})
{ "_id" : "rekoe", "time" : "2017-07-24 15:27:30" }
wcg:PRIMARY> 

但用程序调用

	public void fetch() {
		ZMoCo zMoCo = zMoDB.c(VideoRate.CNAME);
		ZMoDoc old = zMoCo.findOne(ZMoDoc.NEW("{\"_id\":\"rekoe\"}"));
		System.out.println("~~~~~~~~~~~~"+old);
	}

提示错误

2017-08-23 17:23:35,633 [DEBUG][org.mongodb.driver.protocol.query] - Query completed
Exception in thread "main" java.lang.RuntimeException: 'rekoe' not ObjectId
	at org.nutz.lang.Lang.makeThrow(Lang.java:132)
	at org.nutz.mongo.ZMoDoc.put(ZMoDoc.java:497)
	at org.nutz.mongo.ZMoDoc.putAll(ZMoDoc.java:558)
	at org.nutz.mongo.ZMoDoc.NEW(ZMoDoc.java:41)
	at org.nutz.mongo.ZMoDoc.NEW(ZMoDoc.java:82)
	at com.anawin.mongo.StudentService.fetch(StudentService.java:55)
	at com.anawin.mongo.StudentTest.main(StudentTest.java:16)

26 回复

_id 只应该放 ObjectId !! 如果要放自定义的键, 用id

这样

ZMoDoc doc = ZMoDoc.NEW("id", new ObjectId("521c6ffa3004c3c9cbfe59d3"));
        ObjectId id = doc.getAsId("id");
		ZMoDoc old = zMoCo.findOne(ZMoDoc.ID(id));

好绕 感觉

.... 前两句多余吧

@wendal
错误

[12:37:02:036] [ERROR] - com.anawin.tools.IocProvider.me(IocProvider.java:55) - 'anawin' not ObjectId
java.lang.RuntimeException: 'anawin' not ObjectId
	at org.nutz.lang.Lang.makeThrow(Lang.java:132) ~[nutz-1.r.63-SNAPSHOT.jar:1.r.63-SNAPSHOT]
	at org.nutz.mongo.ZMoDoc.put(ZMoDoc.java:497) ~[nutzmongo-1.r.63-SNAPSHOT.jar:?]
	at org.nutz.mongo.ZMoDoc.putv(ZMoDoc.java:125) ~[nutzmongo-1.r.63-SNAPSHOT.jar:?]
	at org.nutz.mongo.ZMoDoc.ID(ZMoDoc.java:50) ~[nutzmongo-1.r.63-SNAPSHOT.jar:?]
	at com.anawin.quartz.job.NotificationUserJob.execute(NotificationUserJob.java:37) ~[om_tools.jar:?]
	at com.anawin.tools.IocProvider.me(IocProvider.java:53) [om_tools.jar:?]
	at com.anawin.tools.IocProvider.main(IocProvider.java:81) [om_tools.jar:?]

调用方法

zMoCo.findOne(ZMoDoc.ID(“anawin”));

findOne(ZMoDoc.ID("521c6ffa3004c3c9cbfe59d3"))

这个大写的ID特指ObjectId

我看控制台打印的语句是

` .find({ "_id" : { "$oid" : "521c6ffa3004c3c9cbfe59d3"}})
但命令行提示错误
PRIMARY> db.user_push.update_time.find({ "_id" : { "$oid" : "521c6ffa3004c3c9cbfe59d3"}})
Error: error: {
"ok" : 0,
"errmsg" : "unknown operator: $oid",
"code" : 2,
"codeName" : "BadValue"
}
wcg:PRIMARY>

@wendal 按照id查询都被转换成了这个命令
{ "_id" : { "$oid" : "521c6ffa3004c3c9cbfe59d3"}}

是报错了吗?

对 好像是ObjectId 必须是特殊格式的才是别 不是字符串就可以的

日志里面的并非执行的内容。。。 那是log_format方法的输出,不一定准确

我想知道是语句报错了,没内容,还是其他情况?

晚上我测一下哦,吃饭先😊

用数据库中的ObjectID数据 599be0a20c187831dc0ffd91 可以查询到
但如果字符串是anawin 也就是 长度不是 上面长度的时候 报

Exception in thread "main" java.lang.RuntimeException: 'anawin' not ObjectId
	at org.nutz.lang.Lang.makeThrow(Lang.java:132)
	at org.nutz.mongo.ZMoDoc.put(ZMoDoc.java:497)
	at org.nutz.mongo.ZMoDoc.putAll(ZMoDoc.java:558)
	at org.nutz.mongo.ZMoDoc.NEW(ZMoDoc.java:41)
	at org.nutz.mongo.ZMoDoc.NEW(ZMoDoc.java:82)
	at com.anawin.mongo.StudentService.fetch(StudentService.java:55)
	at com.anawin.mongo.StudentTest.main(StudentTest.java:16)

查看源码

ObjectId id = new ObjectId(v.toString());
 else if (v instanceof CharSequence) {
                try {
                    ObjectId id = new ObjectId(v.toString());
                    DBobj.put(key, id);
                    return id;
                }
                catch (Exception e) {
                    throw Lang.makeThrow("'%s' not ObjectId", v);
                }
            }

 public ObjectId(final String hexString) {
        this(parseHexString(hexString));
    }

···
private static byte[] parseHexString(final String s) {
if (!isValid(s)) {
throw new IllegalArgumentException("invalid hexadecimal representation of an ObjectId: [" + s + "]");
}

    byte[] b = new byte[12];
    for (int i = 0; i < b.length; i++) {
        b[i] = (byte) Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16);
    }
    return b;
}

···

验证字符的长度了

 public static boolean isValid(final String hexString) {
        if (hexString == null) {
            throw new IllegalArgumentException();
        }

        int len = hexString.length();
        if (len != 24) {
            return false;
        }

        for (int i = 0; i < len; i++) {
            char c = hexString.charAt(i);
            if (c >= '0' && c <= '9') {
                continue;
            }
            if (c >= 'a' && c <= 'f') {
                continue;
            }
            if (c >= 'A' && c <= 'F') {
                continue;
            }

            return false;
        }

        return true;
    }

@Rekoe 你 MongoDB 的版本? 驱动的版本?

mongo-java-driver-3.2.1.jar

 else if (v instanceof CharSequence) {
                try {
                    //ObjectId id = new ObjectId(v.toString());
                    DBobj.put(key, v);
                    return v;
                }
                catch (Exception e) {
                    throw Lang.makeThrow("'%s' not ObjectId", v);
                }
            }

是这样代码的问题 我不验证ObjectId了 直接用这个字符串 就没问题了
修改了 nutzmogodb的源码ZMoDoc 490行

@zozoh 是否可以增加一个方式 支持自定义_id 的。

直接new也可以吧? 不走ZMoDoc.ID就可以了吧?

@wendal 不可以 我尝试用json的参数 也不行

ZMoDoc.json("{"_id":"Rekoe"}")

额, 我想想

ZMoDoc有个大招方法, setDBobj !!

我试试
@wendal

@wendal 是这么用么

ZMoDoc.SET("_id", "rekoe")
ZMoDoc doc = ZMoDoc.NEW();
doc.setDBobj(new BasicDBObject("_id", "rekoe"));

添加回复
请先登陆
回到顶部