【问题标题】:Get counts by merge two collections with conditions in spring data mongodb data通过将两个集合与spring数据mongodb数据中的条件合并来获取计数
【发布时间】:2018-06-27 19:52:20
【问题描述】:

我有两个名为广告和包含的集合。 对于该广告,我需要在当前月份中包含的包含状态为“ACTIVE”和 lastModifiedDate 的计数。

我还有一个关于 adState 是“ACTIVE”的广告条件。

advertisement document
{

    "_id" : ObjectId("1231321321321"),
    "adNumber":1
    "adState" : "ACTIVE"
    "company" : "companyABC",
    "address" : "123 new road",
    "agentName": "Agent_2"
    "lastpublish" : ISODate("2018-01-18T20:20:02.262Z"),
    "createdDate" : ISODate("2018-01-10T16:03:06.694Z"),
    "lastModifiedDate" : ISODate("2018-01-18T20:20:02.262Z"),
    "createdBy" : "yasa",
    "lastModifiedBy" : "System",   
}

    contains documents

{   

    "_id" : ObjectId("465465456456"),
    "adNumber":1
    "containId": 10
    "containState" : "ACTIVE",
    "title" : "Increase sales by 10%",
    "detials" : "buy this solution to incresce ur sale by 10%",
    "agentName": "Agent_2"
    "createdDate" : ISODate("2018-01-11T15:03:06.694Z"),
    "lastModifiedDate" : ISODate("2018-01-11T15:03:06.694Z"),
    "createdBy" : "yasa",
    "lastModifiedBy" : "System",   
}

{    

    "_id" : ObjectId("56565656555"),
    "adNumber":1
    "containId": 11
    "containState" : "IN-ACTIVE",
    "title" : "Land for sale",
    "detials" : "Land near water park for sale",
    "agentName": "Agent_2"
    "createdDate" : ISODate("2018-01-11T15:30:01.694Z"),
    "lastModifiedDate" : ISODate("2018-01-12T15:03:06.694Z"),
    "createdBy" : "yasa",
    "lastModifiedBy" : "System",   
}

{


    "_id" : ObjectId("56887423587"),
    "adNumber":1
    "containId": 12
    "containState" : "ACTIVE",
    "title" : "car for sale",
    "detials" : "BMW for sale",
    "agentName": "Agent_2"
    "createdDate" : ISODate("2018-01-11T15:45:01.690Z"),
    "lastModifiedDate" : ISODate("2018-01-11T15:45:01.690Z"),
    "createdBy" : "yasa",
    "lastModifiedBy" : "System",   
}

给出代码示例以在 java 中将其合并到 spring-data、mongodb 上。

还建议获得结果聚合或映射减少的最佳方法

聚合查询

db.advertisement.aggregate([
  {$match:{"adState": "ACTIVE", "agentName": "Agent_2"}},
  {$lookup:
   {
     from: "contains",
     localField: "adNumber",
     foreignField: "adNumber",
     as: "result_ad"
   }},
{$project:{result_ad:1}},
{$match:{"result_ad": {'$ne': []}}},  
{$unwind:"$result_ad"},
{$match:{"result_ad.containState" : "ACTIVE"}},
{$group: { _id: null, count: { $sum: 1 } }}])

【问题讨论】:

  • 你试过什么?请向我们展示您拥有的代码,有人会从那里帮助您。这两个集合是否相互关联?您预期的输出 json 是什么?添加您用来获得准确答案的所有 pojo。
  • @Veeram 我为此编写了一个 mongodb 查询,我不知道使用 spring-data 也我需要过滤正在进行的月份。我在问题上添加了 mongodb 聚合查询

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


【解决方案1】:

您可以在 spring mongo 2.x 和 Mongo 3.4 版本中尝试下面的 spring 聚合查询。

Instant startofMonth = LocalDate.now()
                .with( TemporalAdjusters.firstDayOfMonth() ).atStartOfDay().toInstant(ZoneOffset.UTC);
Instant endofMonth = LocalDate.now()
                .with( TemporalAdjusters.lastDayOfMonth() ).atTime(LocalTime.MAX).toInstant(ZoneOffset.UTC);

MatchOperation matchOperation = Aggregation.match(Criteria.where("adState").is("ACTIVE").and("agentName").is("Agent_2"));
LookupOperation lookupOperation = LookupOperation.newLookup().
                from("contains").
                localField("adNumber").
                foreignField("adNumber").
                as("result_ad");
UnwindOperation unwindOperation = Aggregation.unwind("result_ad");
MatchOperation matchOperation2 = Aggregation.match(Criteria.where("result_ad.containState").is("ACTIVE").and("result_ad.lastModifiedDate").gte(startofMonth).lte(endofMonth));
CountOperation countOperation = Aggregation.count().as("count");

Aggregation aggregation = Aggregation.newAggregation(matchOperation, lookupOperation, unwindOperation, matchOperation2, countOperation);
Integer results = mongoOperations.aggregate(aggregation, colname, Document.class).getUniqueMappedResult().getInteger("count");

【讨论】:

  • 我想这会很好,但我收到了一个编解码器异常。但我已经用 codec CodecProvider pojoCodecProvider = PojoCodecProvider.builder().register ("com.myapp.domain").build() 注册了 mongoclient; CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(), fromProviders(pojoCodecProvider)); MongoClientURI mongoClientURI = new MongoClientURI(environment.getProperty("mongodb.uri"), MongoClientOptions.builder().codecRegistry(pojoCodecRegistry)); MongoClient mongoClient = new MongoClient(mongoClientURI);返回 mongoClient;
  • 我已经为广告、代理、包含创建了域类,目前还为代理名称添加了 DBref,所以我做了这样的更改 MatchOperation matchOperation = Aggregation.match(Criteria.where("adState").is ("ACTIVE").and("agentName").is(agent)); //代理是对象
  • 您能否更新帖子的所有详细信息或更好地创建一个新问题?很难猜测可能是什么问题。重现步骤将有助于调试问题。
【解决方案2】:

以下是 mongo 聚合管道,您需要获取计数

步骤

  1. $match - 匹配广告 ID
  2. $lookup - 加入包含
  3. $unwind - 将数组拆分为单个文档
  4. $addFields - 检查当前月份的字段
  5. $match - 过滤不匹配的文档
  6. $group - 计算匹配项

你可以把它翻译成JavaSpringMongoRepositories

管道

db.advertisement.aggregate(
    [
        { $match : { "adNumber" : 1 } },
        { $lookup : {
                from : "contains",
                localField : "adNumber",
                foreignField : "adNumber",
                as : "cons"
            }
        },
        { $unwind : "$cons" },
        { $addFields : {
                monthMatch : { $eq : [ { $month : new Date() }, { $month : "$cons.lastModifiedDate" }  ] }
            }
        },
        { $match : { "cons.containState" : "ACTIVE", monthMatch : true} },
        { $group : { _id : null, count : { $sum : 1 } } }
    ]
)

【讨论】:

猜你喜欢
  • 2016-08-01
  • 2013-04-26
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
  • 2021-02-14
  • 1970-01-01
相关资源
最近更新 更多