【发布时间】:2015-04-07 19:15:04
【问题描述】:
这是我的 MongoDB 的示例文档:
user:{
_id:1,
name:'xyz',
age:12,
mobile:21321312,
transaction:[{
trans_id:1,
prod:'a',
purchasedAt:ISODate("2015-02-01"),
},
{
trans_id:2,
prod:'b',
purchasedAt:ISODate("2015-02-01")
},
{
trans_id:3,
prod:'c',
purchasedAt:ISODate("2014-11-24")
}]
,...
}
我的查询如下:
db.user.find({transaction:{$elemMatch:{prod:'a', purchasedAt:ISODate("2015-02-01")}}, transaction:{$elemMatch:{prod:{$nin:['b','c']}, purchasedAt:ISODate("2015-02-01")}}}).count()
我正在尝试获取在日期“2015-02-01”购买产品“a”但未在同一天购买产品 b 和 c 的用户计数。
因此,当尝试在 Java 中使用查询执行此操作时:
coll.find(new BasicDBObject().append("transaction", new BasicDBObject("$elemMatch", new BasicDBObject("prod", 'a').append("purchasedAt", Date))).append("transaction", new BasicDBObject("$elemMatch", new BasicDBObject("prod", new BasicDBObject("$nin",['b','c'])).append("purchasedAt", Date)));
我也试过了:
coll.find(new BasicDBObject("transaction", new BasicDBObject("$elemMatch", new BasicDBObject("prod", 'a').append("purchasedAt", Date))).append("transaction", new BasicDBObject("$elemMatch", new BasicDBObject("prod", new BasicDBObject("$nin",['b','c'])).append("purchasedAt", Date)));
其中Date 是util.Date 对象中的“2015-02-01”。
我发现 Java 忽略了查询的 $in 部分,即它忽略了 {transaction:{$elemMatch:{prod:'a', purchasedAt:ISODate("2015-02-01")}} 并只执行 $nin 部分。
我是通过 DBCursor 对象发现的。
这是光标的输出:
Cursor: Cursor id=0, ns=mydb.user, query={ "transaction" : { "$elemMatch" : { "prod" : { "$nin" : [ "b" , "c"]} , "purchasedAt" : { "$date" : "2015-02-01T00:00:00.000Z"}}}}, numIterated=0, readPreference=primary
因此,我的结果不准确。我想知道为什么完全相同的查询在 Mongo shell 中运行良好,但不适用于 Java API。我的查询结构有什么问题吗?
【问题讨论】:
-
您应该能够在您的
BasicDBObject上使用toString()来查看它正在生成什么查询。当然它忽略了第一部分,因为这是一个Map,并且你使用了两次transaction键。虽然第二个覆盖了第一个。 -
toString()输出也与游标对象相同。Query: { "transaction" : { "$elemMatch" : { "prod" : { "$nin" : [ "b" , "c"]} , "purchasedAt" : { "$date" : "2015-02-01T00:00:00.000Z"}}}} -
查看我评论的第二部分:
BasicDBObject是Map。 -
谢谢,这很有用。但是我怎样才能让 Java 查询这两个部分呢?有没有其他方法可以查询?对于我拥有的查询结构,我无法弄清楚这一点。
-
您可以简单地使用
$and运算符(docs.mongodb.org/manual/reference/operator/query/and)并在其中放置两个transaction查询。这应该有效。
标签: java mongodb api mongodb-query