【问题标题】:How can I implement addFields mongoDB query in Java如何在 Java 中实现 addFields mongoDB 查询
【发布时间】:2019-04-15 03:23:24
【问题描述】:

我在 StackOverFlow 上找到了几个与聚合中的 addFields 相关的示例。 但是没有人用 Java 实现。

db.getCollection('myDocument').aggregate([
    {$match : {"metaId.ref.uuid" : "d6112808-1ce1-4545-bd52-cf55bc4ed25e"}},
    {$lookup: {from: "simple", localField: "someId.ref.uuid", foreignField: "uuid", 
    as: "simple"}},
    {"$unwind": "$simple"},
    {"$addFields": { "metaId.ref.name" : "$simple.name" }}
])

我无法在 Java 中正确实现:-- 没有得到正确的程序

   LookupOperation lookupOperation =LookupOperation.newLookup().from("simple").localField("execId.ref.uuid").foreignField("uuid").as("simple");
            Aggregation myDocAggr = newAggregation(match(Criteria.where("metaId.ref.uuid").is(someUUID)), group("uuid").max("version").as("version"),
                    lookupOperation,
                    Aggregates.unwind(""),
                Aggregates.addFields(fields));
            Document document =new Document();
            AggregationResults<String> myDocAggrResults = mongoTemplate.aggregate(myDocAggr , myDocument, myDocument.class);
            List<String> mydocumentList = myDocAggrResults .getMappedResults();

无法使用 unwind 和 addFields,这是示例 java 代码,但不行。 请帮我。在此先感谢

【问题讨论】:

  • 哪个错误/堆栈跟踪?
  • 编译错误是什么意思?
  • 我猜至少缺少一个右括号
  • Aggregates.unwind(""), 之后应该有一些右括号?你想为方法调用提供什么参数?
  • 您尝试调用哪个newAggregation 方法?

标签: java mongodb mongodb-query aggregation-framework spring-data-mongodb


【解决方案1】:

您正在将 java 驱动程序 Aggregates 方法与 Spring Aggregation 方法混合。

$addFields 在 spring mongo 中仍然是 not supported

你必须使用下面的聚合。

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
Aggregation myDocAggr = newAggregation(
       match(Criteria.where("metaId.ref.uuid").is(someUUID)), 
       group("uuid").max("version").as("version"),
       lookup("simple","execId.ref.uuid","uuid","simple"),
       unwind("simple"),
       new AggregationOperation(){ 
         @Override 
         public Document toDocument(AggregationOperationContext aoc) {
            return new Document("$addFields",new Document("metaId.ref.name","$simple.name"));
         }
      }
)
List<Document> mydocumentList=mongoTemplate.aggregate(myDocAggr,"myDocument",Document.class).getMappedResults();

【讨论】:

  • 此代码 sn-p 使用的是哪个版本的 spring,我无法在我的代码中添加展开和查找。
  • 感谢您提供解决方案 :-) 虽然 unwind 对我不起作用,但我有办法实现它。
  • 不客气。使用import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;。它具有所有聚合运算符。
  • 我有限制,不能使用大于1.90的mongo_spring_data所以我已经切换到mongo java驱动,因为我有大量的记录,想使用游标,请告诉我如何添加字段,使用java.
  • 不要将 spring 聚合与 java 驱动程序聚合混合和匹配。 Aggregates.addFields(new Field("metaId.ref.name", "$simple.name")) 之类的东西应该适用于 java 驱动程序。将其余聚合运算符转换为使用 java 驱动程序。
【解决方案2】:

虽然spring mongo不支持$addFields,但是你可以自己实现:

import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.*;
import java.util.LinkedHashMap;
import java.util.Map;

public class AddFieldsOperation implements FieldsExposingAggregationOperation {
    private Map<String, Object> fields = new LinkedHashMap<>();

    public AddFieldsOperation(String field, AggregationExpression expression) {
        addField(field, expression);
    }

    public AddFieldsOperation addField(String field, AggregationExpression expression) {
        this.fields.put(field, expression.toDocument(Aggregation.DEFAULT_CONTEXT));
        return this;
    }

    @Override
    public Document toDocument(AggregationOperationContext context) {
        Document doc = new Document();
        fields.forEach(doc::append);
        return new Document("$addFields", doc);
    }

    @Override
    public boolean inheritsFields() {
        return true;
    }

    @Override
    public ExposedFields getFields() {
        final String[] fieldsArray = fields.keySet().toArray(new String[0]);
        return ExposedFields.synthetic(Fields.fields(fieldsArray));
    }

并像这样使用它:

...
ArithmeticOperators.Add value1 = ArithmeticOperators.Add.valueOf(0);
ArithmeticOperators.Add value2 = ArithmeticOperators.Add.valueOf(0);
AddFieldsOperation addFields
            = new AddFieldsOperation("value1", value1)
            .addField("value2", value2);
pipeline.add(addFields);
...
Add value1PlusValue2 = Add.valueOf("$value1").add("$value2");
...

希望对某人有所帮助。

【讨论】:

    【解决方案3】:

    从'spring-data-mongodb' 3.0 版开始,实际上可以很容易地创建一个AddField 聚合。您可以使用AddFieldsOperationBuilder

    在下面的示例中,我为名为 _id 的 objectId 字段添加了一个字符串 id 字段。 字符串字段idString 可以在查找聚合中使用。

    例子:

        AddFieldsOperation addFieldsOperation = Aggregation.addFields().addFieldWithValue("idString", ConvertOperators.ToString.toString("$_id")).build();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多