Spring Data MongoDB 教程

脚本操作

本文将介绍怎样使用 Spring Data MongoDB 提供的 ScriptOperations,在 MongoDB 上执行 JavaScript 脚本。

MongoDB 允许通过直接发送脚本或调用存储的脚本在服务器上运行 JavaScript 函数。

MongoDB 4.2 移除了被 ScriptOperations 使用的 eval 命令的支持,并且没有提供其他替代方案。因此,ScriptOperations 不在推荐使用,该接口的声明如下:

package org.springframework.data.mongodb.core;

import java.util.Set;

import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import org.springframework.lang.Nullable;


/**
* Script operations on {@link com.mongodb.client.MongoDatabase} level. Allows interaction with server side JavaScript functions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
* @deprecated since 2.2. The {@code eval} command has been removed without replacement in MongoDB Server 4.2.0.
*/
@Deprecated
public interface ScriptOperations {
   //...
}

官方已经不推荐使用了,但还是有必要看看它是干什么的。

ScriptOperations 可以通过 MongoTemplate 的 scriptOps() 方法获取,ScriptOperations 并为 JavaScript 的使用提供基本的抽象。scriptOps() 方法定义如下:

  • ScriptOperations scriptOps() 返回可以在 MongoDatabase 级别上执行的 ScriptOperations 对象。

ScriptOperations 接口定义的主要方法如下:

  • Object all(String scriptName, Object... args) 用它的名字调用 JavaScript。

  • Object execute(ExecutableMongoScript script, Object... args) 执行脚本,通过它的名字调用它或直接发送它。

  • boolean exists(String scriptName) 检查 MongoDatabase 中是否存在给定名称的服务器端 JavaScript。

  • Set<String> getScriptNames() 返回可以调用的 JavaScript 函数的名称。

  • NamedMongoScript register(ExecutableMongoScript script) 存储给定的 ExecutableMongoScript 对象,生成一个名称,以便随后可以通过名称来调用。

  • NamedMongoScript register(NamedMongoScript script) 在数据库中注册给定的名称 MongoScript。

示例

(1)直接运行 JavaScript 脚本,使用 ExecutableMongoScript 定义一个可执行的 JavaScript 脚本,代码如下:

ScriptOperations scriptOps = template.scriptOps();
// 定义一个脚本
ExecutableMongoScript echoScript = new ExecutableMongoScript("function(x) { return x; }");
// 直接运行脚本
scriptOps.execute(echoScript, "directly execute script");

(2)通过脚本名称运行脚本,代码如下:

ScriptOperations scriptOps = template.scriptOps();
// 定义一个脚本
ExecutableMongoScript echoScript = new ExecutableMongoScript("function(x) { return x; }");
// 使用 echo 名称注册 echoScript 脚本
scriptOps.register(new NamedMongoScript("echo", echoScript));
// 通过 echo 名称执行脚本
scriptOps.call("echo", "execute script via name");

完整实例代码

下面是通过 ScriptOperations 执行脚本的完整代码,如下:

package com.hxstrive.springdata.mongodb;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.ScriptOperations;
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
import org.springframework.data.mongodb.core.script.NamedMongoScript;

/**
* ScriptOperations 操作 JavaScript 脚本
* @author hxstrive.com
*/
@SpringBootTest
class ScriptOperationsDemo {

   @Autowired
   private MongoTemplate mongoTemplate;


   @Test
   public void directlyExecuteScript() {
       // 获取 ScriptOperations 对象
       ScriptOperations scriptOps = mongoTemplate.scriptOps();

       // 创建一个简单的脚本
       // 将接收的参数 x 前后添加固定字符,然后返回
       ExecutableMongoScript echoScript = new ExecutableMongoScript("function(x) { return '[' + x + ']'; }");

       // 执行脚本
       Object result = scriptOps.execute(echoScript, "directly execute script");
       System.out.println(result);
       // 结果:
       // [directly execute script]
       // 注意:笔者运行的 MongoDB 版本为 3.4.15,在 5.0.14 版本运行抛出如下错误:
       // com.mongodb.MongoCommandException: Command failed with error 59 (CommandNotFound):
       // 'no such command: '$eval'' on server localhost:27017.
       // The full response is {"ok": 0.0, "errmsg": "no such command: '$eval'", "code": 59,
       // "codeName": "CommandNotFound"}
   }

   @Test
   public void directlyExecuteScript2() {
       ScriptOperations scriptOps = mongoTemplate.scriptOps();

       // 定义一个脚本
       ExecutableMongoScript echoScript = new ExecutableMongoScript("function(x) { return '[' + x + ']'; }");

       // 使用 echo 名称注册 echoScript 脚本
       scriptOps.register(new NamedMongoScript("echo", echoScript));

       // 通过 echo 名称执行脚本
       Object result = scriptOps.call("echo", "execute script via name");
       System.out.println(result);
       // 结果:
       // [execute script via name]
   }

}

其中,Person 实体类的代码如下:

package com.hxstrive.springdata.mongodb.entity;

import lombok.Builder;
import lombok.Data;
import lombok.ToString;

@Data
@ToString
@Builder
public class Person {
   /** 用户ID */
   private int id;
   /** 用户姓名 */
   private String name;
   /** 年龄 */
   private int age;
   /** 电子邮件 */
   private String email;
}
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号