草庐IT

java - mongo java 条件和如果不为空

coder 2023-11-02 原文

我正在使用 mongo java 驱动程序并尝试计算特定字段不为空或不存在的所有文档。这是我到目前为止所拥有的:

String field = "myfieldname";
BasicDBObject notNull = new BasicDBObject(field,BasicDBObject("$ne",null));
List<Object> condition = Arrays.asList(notNull,1,0);
BasicDBObject aggregation = new BasicDBObject("$cond",condition);
// boiler plate code to lookup my database/collection and pass the aggregation to it

这似乎行不通。

编辑: 感谢 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);

最佳答案

这是一个实现我认为您想要的逻辑的应用程序。它使用 Asynchronous Java Driver's 帮助程序类来帮助构建正确的管道。在代码的末尾,我们插入了 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
}]

我接近了吗? 罗布。

关于java - mongo java 条件和如果不为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20964169/

有关java - mongo java 条件和如果不为空的更多相关文章

  1. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  2. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  3. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  4. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  5. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  6. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  7. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  8. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  9. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  10. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

随机推荐