我正在使用mongo java驱动程序并尝试计算特定字段不为null或不存在的所有文档.这是我到目前为止所拥有的:
String field = "myfieldname"; BasicDBObject notNull = new BasicDBObject(field,BasicDBObject("$ne",null)); List
这似乎不起作用.
编辑:感谢Rob Moore的帮助.以下是我最终要做的工作
BasicDBObject ifNull = new BasicDBObject('$ifNull',Arrays.asList('$'+field,null)); BasicDBObject neq = new BasicDBObject('$ne', Arrays.asList(null,ifNull)); return new BasicDBObject('$cond', Arrays.asList(neq,1,0);
Rob Moore.. 5
这是一个实现我认为你所追求的逻辑的应用程序.它使用异步Java驱动程序的帮助程序类来帮助构建正确的管道.在代码的最后,我们插入了99个文档.33具有空字段值,33具有值,33没有值.该应用程序共有66个,我认为这是你追求的结果.
/*
* Copyright 2013 - Allanbank Consulting, Inc.
*
* 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 stackoverflow;
import static com.allanbank.mongodb.builder.AggregationGroupField.set;
import static com.allanbank.mongodb.builder.AggregationGroupId.constantId;
import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
import static com.allanbank.mongodb.builder.Find.ALL;
import static com.allanbank.mongodb.builder.expression.Expressions.cond;
import static com.allanbank.mongodb.builder.expression.Expressions.constant;
import static com.allanbank.mongodb.builder.expression.Expressions.eq;
import static com.allanbank.mongodb.builder.expression.Expressions.field;
import static com.allanbank.mongodb.builder.expression.Expressions.ifNull;
import static com.allanbank.mongodb.builder.expression.Expressions.set;
import java.io.IOException;
import java.util.Random;
import com.allanbank.mongodb.MongoClient;
import com.allanbank.mongodb.MongoCollection;
import com.allanbank.mongodb.MongoFactory;
import com.allanbank.mongodb.bson.builder.BuilderFactory;
import com.allanbank.mongodb.bson.builder.DocumentBuilder;
import com.allanbank.mongodb.bson.element.ArrayElement;
import com.allanbank.mongodb.bson.element.ObjectId;
import com.allanbank.mongodb.builder.Aggregate;
/**
* Count the number of documents that have a particular field.
*
* @see StackOverflow
* Question
*
* @copyright 2013, Allanbank Consulting, Inc., All Rights Reserved
*/
public class SumIfExists {
/**
* A source of no so random values. Use a fixed seed to always get the same
* values for fields.
*/
private final static Random random = new Random(123456789L);
/**
* The handle to the MongoDB client. We assume MongoDB is running on your
* machine on the default port of 27017.
*/
private final static MongoClient client = MongoFactory
.createClient("mongodb://localhost:27017/");
/** The collection we will be using. */
private final static MongoCollection theCollection = client.getDatabase(
"db").getCollection("collection");
/**
* Run the demo.
*
* @param args
* Command line arguments. Ignored.
* @throws IOException
* On a failure closing the MongoCLient.
*/
public static void main(String[] args) throws IOException {
// Build the aggregation document/command.
Aggregate.Builder builder = Aggregate.builder();
// From the StackOverflow Question.
String fieldName = "myfieldname";
// A token ObjectId to use in comparisons for the null field.
ObjectId nullToken = new ObjectId();
builder.project(
include("a", "b", "c", "etc"),
set("myfieldnameExists",
cond(eq(ifNull(field(fieldName), constant(nullToken)),
constant(nullToken)), constant(0), constant(1))));
builder.group(constantId("a"), set("count").sum("myfieldnameExists"));
System.out.println(new ArrayElement("$pipeline", builder.build()
.getPipeline()));
// Insert some documents to test with.
theCollection.delete(ALL);
for (int i = 0; i < 99; ++i) {
DocumentBuilder doc = BuilderFactory.start();
if (i % 3 == 0) {
doc.addNull(fieldName);
}
else if (i % 3 == 1) {
doc.add(fieldName, random.nextDouble());
}
// else if (i % 3 == 2) -- Field does not exist.
doc.add("a", random.nextBoolean());
doc.add("b", random.nextInt());
doc.add("c", random.nextLong());
doc.add("etc", random.nextLong());
theCollection.insert(doc);
}
// Run the aggregation.
System.out.println(theCollection.aggregate(builder));
}
}
代码的输出是:
'$pipeline' : [ { '$project' : { a : 1, b : 1, c : 1, etc : 1, myfieldnameExists : { '$cond' : [ { '$eq' : [ { '$ifNull' : [ '$myfieldname', ObjectId('52cb94836c4a28185433c4d3') ] }, ObjectId('52cb94836c4a28185433c4d3') ] }, 0, 1 ] } } }, { '$group' : { '_id' : 'a', count : { '$sum' : '$myfieldnameExists' } } } ] [{ '_id' : 'a', count : 66 }]
我接近了吗?抢.
这是一个实现我认为你所追求的逻辑的应用程序.它使用异步Java驱动程序的帮助程序类来帮助构建正确的管道.在代码的最后,我们插入了99个文档.33具有空字段值,33具有值,33没有值.该应用程序共有66个,我认为这是你追求的结果.
/*
* Copyright 2013 - Allanbank Consulting, Inc.
*
* 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 stackoverflow;
import static com.allanbank.mongodb.builder.AggregationGroupField.set;
import static com.allanbank.mongodb.builder.AggregationGroupId.constantId;
import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
import static com.allanbank.mongodb.builder.Find.ALL;
import static com.allanbank.mongodb.builder.expression.Expressions.cond;
import static com.allanbank.mongodb.builder.expression.Expressions.constant;
import static com.allanbank.mongodb.builder.expression.Expressions.eq;
import static com.allanbank.mongodb.builder.expression.Expressions.field;
import static com.allanbank.mongodb.builder.expression.Expressions.ifNull;
import static com.allanbank.mongodb.builder.expression.Expressions.set;
import java.io.IOException;
import java.util.Random;
import com.allanbank.mongodb.MongoClient;
import com.allanbank.mongodb.MongoCollection;
import com.allanbank.mongodb.MongoFactory;
import com.allanbank.mongodb.bson.builder.BuilderFactory;
import com.allanbank.mongodb.bson.builder.DocumentBuilder;
import com.allanbank.mongodb.bson.element.ArrayElement;
import com.allanbank.mongodb.bson.element.ObjectId;
import com.allanbank.mongodb.builder.Aggregate;
/**
* Count the number of documents that have a particular field.
*
* @see <a
* href="http://stackoverflow.com/questions/20964169/mongo-java-conditional-sum-if-exists">StackOverflow
* Question</a>
*
* @copyright 2013, Allanbank Consulting, Inc., All Rights Reserved
*/
public class SumIfExists {
/**
* A source of no so random values. Use a fixed seed to always get the same
* values for fields.
*/
private final static Random random = new Random(123456789L);
/**
* The handle to the MongoDB client. We assume MongoDB is running on your
* machine on the default port of 27017.
*/
private final static MongoClient client = MongoFactory
.createClient("mongodb://localhost:27017/");
/** The collection we will be using. */
private final static MongoCollection theCollection = client.getDatabase(
"db").getCollection("collection");
/**
* Run the demo.
*
* @param args
* Command line arguments. Ignored.
* @throws IOException
* On a failure closing the MongoCLient.
*/
public static void main(String[] args) throws IOException {
// Build the aggregation document/command.
Aggregate.Builder builder = Aggregate.builder();
// From the StackOverflow Question.
String fieldName = "myfieldname";
// A token ObjectId to use in comparisons for the null field.
ObjectId nullToken = new ObjectId();
builder.project(
include("a", "b", "c", "etc"),
set("myfieldnameExists",
cond(eq(ifNull(field(fieldName), constant(nullToken)),
constant(nullToken)), constant(0), constant(1))));
builder.group(constantId("a"), set("count").sum("myfieldnameExists"));
System.out.println(new ArrayElement("$pipeline", builder.build()
.getPipeline()));
// Insert some documents to test with.
theCollection.delete(ALL);
for (int i = 0; i < 99; ++i) {
DocumentBuilder doc = BuilderFactory.start();
if (i % 3 == 0) {
doc.addNull(fieldName);
}
else if (i % 3 == 1) {
doc.add(fieldName, random.nextDouble());
}
// else if (i % 3 == 2) -- Field does not exist.
doc.add("a", random.nextBoolean());
doc.add("b", random.nextInt());
doc.add("c", random.nextLong());
doc.add("etc", random.nextLong());
theCollection.insert(doc);
}
// Run the aggregation.
System.out.println(theCollection.aggregate(builder));
}
}
代码的输出是:
'$pipeline' : [ { '$project' : { a : 1, b : 1, c : 1, etc : 1, myfieldnameExists : { '$cond' : [ { '$eq' : [ { '$ifNull' : [ '$myfieldname', ObjectId('52cb94836c4a28185433c4d3') ] }, ObjectId('52cb94836c4a28185433c4d3') ] }, 0, 1 ] } } }, { '$group' : { '_id' : 'a', count : { '$sum' : '$myfieldnameExists' } } } ] [{ '_id' : 'a', count : 66 }]
我接近了吗?抢.