Spring Data MongoDB - 与其他集合的聚合

2023-12-07

我正在尝试Spring Boot v.2.1.3.RELEASE 和 Spring Data MongoDB。由于关键要求,我必须像下面这样进行建模,假设员工了解多种技术,但主要语言是任何人。

因此,我决定将技术集合分开,并在员工集合中以某种方式将员工和技术相关联。

{
    "_id" : ObjectId("5ec65750fdcd4e960f4b2f24"),
    "technologyCd" : "AB",
    "technologyName" : "My ABC",
    "ltechnologyNativeName" : "XY",
    "status" : "A"
}

所以,我做了如下关联 -

注意:一名员工可以关联多种技术

一名员工可以与多种技术相关联

员工只能拥有一项且仅有一项主要技术

{
    "_id" : ObjectId("5ec507c72d8c2136245d35ce"),
    "firstName" : "John",
    "lastName" : "Doe",
    "email" : "[email protected]",
    .......
    .......
    .......
    "employeeTechnologyRefs" : [ 
        {
            "technologyCd" : "AB",
            "primaryTechnologySw" : "Y",
            "Active" : "A"
        }, 
        {
            "technologyCd" : "AB",
            "primaryTechnologySw" : "N",
            "Active" : "A"
        }, 
        {
            "technologyCd" : "PR",
            "primaryTechnologySw" : "N",
            "Active" : "A"
        }, 
        {
            "technologyCd" : "PR",
            "primaryTechnologySw" : "N",
            "Active" : "A"
        }
    ],
    "countryPhoneCodes" : [ 
        "+352"
    ],
    ....
    ...
}

我使用了下面的查询,如何查询技术文档以获取结果并将其映射并创建最终对象?

Criteria criteria = new Criteria();
criteria.andOperator(
        StringUtils.isNotBlank(firstName) ? Criteria.where("firstName").is(firstName.toUpperCase())
                : Criteria.where(""),
        StringUtils.isNotBlank(lastName) ? Criteria.where("lastName").is(lastName.toUpperCase())
                : Criteria.where(""),
        StringUtils.isNotBlank(email) ? Criteria.where("email").is(email.toUpperCase())
                : Criteria.where(""),
        StringUtils.isNotBlank(technologyCd) ? Criteria.where("employeeTechnologyRefs.technologyCd").is(technologyCd.toUpperCase())
                : Criteria.where(""));

MatchOperation matchStage = Aggregation.match(criteria);

GroupOperation groupOp = Aggregation
        .group("firstName", "lastName", "email","_id")
        .addToSet("employeeTechnologyRefs").as("employeeTechnologyRefs");

ProjectionOperation projectStage = Aggregation.project("employeeTechnologyRefs");

Aggregation aggregation = Aggregation.newAggregation(matchStage, groupOp, projectStage);

AggregationResults<CustomObject> results = mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(Employee.class), CustomObject.class);
System.out.println(results);

结果应如下所示

{
    "_id" : ObjectId("5ec507c72d8c2136245d35ce"),
    "firstName" : 442,
    "lastName" : "LU",
    "email" : "LUX",
    .......
    .......
    .......
    "employeeTechnologyRefs" : [ 
        {
            "technologyCd" : "AB",
            "technologyName" : "My ABC",
            "ltechnologyNativeName" : "XY",
            "primaryTechnologySw" : "Y",
            "Active" : "A"
        }, 
        {
            "technologyCd" : "AB",
            "technologyCd" : "AB",
            "technologyName" : "My ABC",
            "ltechnologyNativeName" : "XY",
            "primaryTechnologySw" : "Y",
            "Active" : "A"
        }, 
        {
            "technologyCd" : "PR",
            "technologyCd" : "AB",
            "technologyName" : "My ABC",
            "ltechnologyNativeName" : "XY",
            "primaryTechnologySw" : "Y",
            "Active" : "A"
        }, 
        {
            "technologyCd" : "PR",
            "technologyCd" : "AB",
            "technologyName" : "My ABC",
            "ltechnologyNativeName" : "XY",
            "primaryTechnologySw" : "Y",
            "Active" : "A"
        }
    ],
    ....
    
}

如果您在代码中使用以下查找操作,您应该能够获得预期的答案,并且不需要在代码中进行分组操作。

编辑后的答案:整个代码应该是这样的。另一件事是,您不需要投影,如果需要,请尝试仅投影特定字段,并且作为查找操作的一部分,不要使用与集合中相同的字段,否则它将覆盖员工集合中的现有数据。

    Criteria criteria = new Criteria();
    criteria.andOperator(
            StringUtils.isNotBlank(firstName) ? Criteria.where("firstName").is(firstName.toUpperCase())
                    : Criteria.where(""),
            StringUtils.isNotBlank(lastName) ? Criteria.where("lastName").is(lastName.toUpperCase())
                    : Criteria.where(""),
            StringUtils.isNotBlank(email) ? Criteria.where("email").is(email.toUpperCase())
                    : Criteria.where(""),
            StringUtils.isNotBlank(technologyCd) ? Criteria.where("employeeTechnologyRefs.technologyCd").is(technologyCd.toUpperCase())
                    : Criteria.where(""));

    MatchOperation matchStage = Aggregation.match(criteria);

    /*GroupOperation groupOp = Aggregation
            .group("firstName", "lastName", "email","_id")
            .addToSet("employeeTechnologyRefs").as("employeeTechnologyRefs");
            */

    LookupOperation lookupOperation = LookupOperation.newLookup().
                                     from("technology_collection_name").
                                     localField("employeeTechnologyRefs.technologyCd").
                                     foreignField("technologyCd").
                                     as("employeeTechnologyRefsOtherName");

   /* ProjectionOperation projectStage = Aggregation.project("employeeTechnologyRefs");
  */  
// And if you want to project specific field from employee array you can use something like.
ProjectionOperation projectStage = Aggregation.project("employeeTechnologyRefs.fieldName")
    Aggregation aggregation = Aggregation.newAggregation(matchStage, lookupOperation, projectStage);

    AggregationResults<CustomObject> results = mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(Employee.class), CustomObject.class);
    System.out.println(results);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Data MongoDB - 与其他集合的聚合 的相关文章

随机推荐

  • 为什么无穷大在 Windows 10 控制台中打印为“8”?

    我正在测试除法返回的内容 包括零 即0 1 1 0 and 0 0 为此 我使用了类似于以下内容的内容 Console WriteLine 1d 0d 然而这段代码打印8 not Infinity或其他一些字符串常量 例如PositiveI
  • PropertyGrid - 根据另一个属性值更改下拉属性编辑器的项目

    我正在尝试在自定义组件中实现下拉属性 并且我使用了这个答案 and 这个答案作为指导 到目前为止 我设法让它工作 并在下拉列表中使用预定义的项目 但我仍然需要弄清楚如何更改下拉列表中的项目 这是我到目前为止的代码 从上面提到的链接构建 Ty
  • 静态javascript未在jade中呈现(使用express/node.js)

    我希望你一切都好 我突然无法在 jade 模板中渲染任何外部 javascript 为了弄清楚事情的真相 我将其精简到最低限度 节点0 6 11 Express 2 5 8 jade 0 20 3 app js var express re
  • 协调两个对象集合

    我有一个表单 用户可以在其中使用 DataGrid 修改对象集合 打开表单时 我会创建原始集合的深层副本 如果按下 取消 按钮 我只会丢弃该副本 问题是 当按下 确定 按钮时 我必须协调可能的更改 修改现有对象的属性 新对象添加到集合中的任
  • Log4j JDK 日志适配器:在启动过程后期应用 LogManager 系统属性

    我有一个运行 Web 应用程序的 WebSphere 应用程序服务器 我从 Eclipse 启动服务器 该应用程序中的主要日志记录框架是 log4j2 但也有一些使用 java util logging 的第三方库 我想将这些日志重定向到
  • 实时网络编程:它是如何工作的?

    作为一名 Web 开发人员 我借助 Redis 或 Pusher 等第三方服务开发了聊天服务和其他一些实时协作服务 它们提供了简单的 API 我可以使用发布 订阅模型来实现通过网络服务器的双向通信 我现在想实现一个简单的推送通知 而不使用任
  • 阻止选择下拉列表打开,但允许触发其事件

    有什么方法可以捕获 html select 事件 并阻止 html select 下拉列表打开吗 禁用 html select 被排除 因为事件也将被禁用 我怀疑这实际上会阻止它打开 但它将确保 DropDown 始终保持相同的值
  • 如何根据其中一个成员的值对结构数组进行排序,并根据另一个成员打破联系?

    假设有一个结构 struct x int a b c 结构体数组包含arr 0 4 2 5 arr 1 6 3 1 arr 2 4 1 8 那么我们如何根据成员 a 的值按升序对这个数组进行排序 将根据成员 b 的值打破平局 所以排序后的数
  • ReaderT 设计模式:参数化环境

    我基于以下内容构建了一个项目ReaderT设计模式 我选择使用简单的处理程序注入作为函数参数 而不是使用类型类方法进行依赖项注入 这部分工作得很好 因为我们能够静态构建依赖树并动态定义环境 环境可能包含配置以及日志记录效果 String g
  • 您可以在迭代 std::list 时从其中删除元素吗?

    我的代码如下所示 for std list
  • 是否有 Visual Studio 宏可以在类中每个方法的开头设置断点?

    是否有 Visual Studio 宏 版本 2008 或 2010 可以在类中每个方法的开头设置断点 我已经看到了参考文献的提示 但我无法挖掘出真正的参考文献 名为的 Visual Studio 扩展OzCode确实具有在类的所有成员上设
  • 检测外部进程是否是交互式的并且有任何可见的 UI

    我似乎无法找到一种方法来确定是否Process有一个用户界面 例如一个用户可见的窗口 Environment UserInteractive对于外部进程没有用处 process MainWindowHandle IntPtr Zero在我的
  • 在 swift 中表达具有动态范围的 for 循环

    或者我如何在 for 循环条件中使用索引 嘿人们 由于我们在 swift 3 中没有 c 风格的 for 循环 我似乎找不到一种方法来表达更复杂的 for 循环 所以也许你可以帮助我 如果我写这个 for int i 5 num i gt
  • 面板之间切换

    我有 1 个表单中的 3 个面板来完成输入某些数据的过程 单击面板中的下一个按钮时 应显示下一个面板 最初 我启用了第一个面板的可见性并禁用了其他面板的可见性 当单击下一个按钮时 将执行以下代码 panel1 Visible false p
  • PHP:以五个为一组显示数据库中的条目?

    是否可能 如果可以 我该怎么做 选择数据库表中的所有条目 然后在一组中同时显示五个结果 含义 举个例子 我的数据库中有 15 条记录 那么我想像这样呈现我的数据 div class 1 5 Record 1 Record 2 Record
  • 如何使用 Tensorflow 1.0 Java API 创建/初始化变量

    我正在尝试移植这行Python代码 my var tf Variable 3 name input a 到爪哇 我能够做到这一点tf constant这样 graph opBuilder Const name setAttr dtype t
  • matplotlib轮廓图中的对称对数色阶

    如何创建具有符号对数 对称对数 比例的等高线图 即显示负值和正值的对数刻度 一种可能性是解决这个例子 http matplotlib org examples pylab examples contourf log html 这给出了对数刻
  • 如何停止 SAS 中的“锁不可用于 <数据集>”错误?

    运行 SAS 程序时 我总是收到 锁不可用 错误 如果我在一个程序中多次对同一数据集执行操作 通常会发生这种情况 研究此错误后 我了解到这意味着两个程序正在尝试访问同一数据集 换句话说 这类似于尝试打开其他人或您自己已在使用的文档 这是给我
  • Wait() 和 Notify() 概念 - Java 多线程

    class Q volatile boolean valueSet false volatile int n synchronized int get if valueSet try wait catch InterruptedExcept
  • Spring Data MongoDB - 与其他集合的聚合

    我正在尝试Spring Boot v 2 1 3 RELEASE 和 Spring Data MongoDB 由于关键要求 我必须像下面这样进行建模 假设员工了解多种技术 但主要语言是任何人 因此 我决定将技术集合分开 并在员工集合中以某种