使用JSONiq插入JSON

时间:2016-12-21 15:55:22

标签: json zorba jsoniq

我们正在编写JSONiq查询以将新属性插入到JSON中,并从查询中返回更新的JSON。

查询:

users

java.lang.RuntimeException: (no URI):13,1: static error [err:XPST0003]: invalid expression: syntax error, unexpected expression (missing comma "," between expressions?) 包含输入json,我们正在尝试使用JSONiq insert命令添加一个属性,如JSONiq文档中所述here

我们正在低于例外:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.knodeit</groupId>
    <artifactId>try</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>try</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq</artifactId>
            <version>3.7.4</version>
        </dependency>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq-meta</artifactId>
            <version>3.7.4</version>
        </dependency>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq-codegen</artifactId>
            <version>3.7.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <profiles>

        <profile>
            <id>mysql</id>
            <build>
                <plugins>
                    <plugin>

                        <groupId>org.jooq</groupId>
                        <artifactId>jooq-codegen-maven</artifactId>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>generate</goal>
                                </goals>
                            </execution>
                        </executions>
                        <dependencies>
                            <dependency>
                                <groupId>mysql</groupId>
                                <artifactId>mysql-connector-java</artifactId>
                                <version>${mysql.version}</version>
                            </dependency>
                        </dependencies>
                        <configuration>
                            <jdbc>
                                <driver>com.mysql.jdbc.Driver</driver>
                                <url>jdbc:mysql://localhost:3306</url>
                                <user>root</user>
                                <password>root</password>

                            </jdbc>
                            <generator>
                                <name>org.jooq.util.JavaGenerator</name>
                                <database>
                                    <name>org.jooq.util.mysql.MySQLDatabase</name>
                                    <includes>.*</includes>
                                    <excludes />
                                    <inputSchema>demo</inputSchema>
                                </database>
                                <generate>
                                    <relations>true</relations>
                                    <deprecated>false</deprecated>
                                    <instanceFields>true</instanceFields>
                                    <generatedAnnotation>true</generatedAnnotation>
                                    <records>true</records>
                                    <pojos>true</pojos>
                                    <immutablePojos>false</immutablePojos>
                                    <interfaces>true</interfaces>
                                    <daos>true</daos>
                                    <jpaAnnotations>true</jpaAnnotations>
                                    <validationAnnotations>true</validationAnnotations>
                                    <springAnnotations>true</springAnnotations>
                                    <globalObjectReferences>true</globalObjectReferences>
                                    <fluentSetters>false</fluentSetters>
                                </generate>
                                <target>
                                    <packageName>com.knodeit.jooq.domain</packageName>
                                    <directory>jooq</directory>
                                </target>
                            </generator>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>


</project>

问题:

  1. 查询是否正确?如果没有,如何在语法/逻辑上使其正确?
  2. JSONiq是否有任何可用的在线资源?

2 个答案:

答案 0 :(得分:1)

这是使用JSONiq使json更新工作的方法。我们需要使用copy-modify-return子句:

jsoniq version "1.0";
copy $users := {
      "name" : "Deadbeat Jim",
      "address" : "1 E 161st St, Bronx, NY 10451",
      "risk tolerance" : "high"
} 
modify insert json {"status" : "credit card declined"} into $users
return $users

希望这对某人有帮助

答案 1 :(得分:0)

以下是一些解释:

JSONiq更新工作的方式与XQuery更新的工作方式相同。 JSONiq更新是声明性的:除了数据模型中的空序列之外,JSONiq更新程序还返回所谓的待定更新列表(PUL),这是一个要应用于某些文档的更新列表(删除,替换,重命名,插入等)。

JSONiq更新具有快照语义,这意味着在评估主表达式时会出现无副作用。相反,计算PUL之后,引擎可以将PUL指定的更改传播到底层存储(例如磁盘上的文件或文档存储)。

问题的例子的语法正确版本将是:

jsoniq version "1.0";
let $users := {
  "name" : "Deadbeat Jim",
  "address" : "1 E 161st St, Bronx, NY 10451",
  "risk tolerance" : "high"
} 
return insert json {"status" : "credit card declined"} into $users

但是,在这种情况下,返回的PUL包含对内存中动态创建的JSON对象的更改。该对象的生命周期只是查询评估的生命周期,因此该程序根本没有明显效果。

如果collection函数以某种方式映射到文档存储中的数据库(如Couchbase或MongoDB)(即,如果引擎已记录并配置为执行此操作),则以下查询将在语义上应用更新到此文档商店。

jsoniq version "1.0";
let $users := collection("users")[$$.name eq "Jim"]
return insert json {"status" : "credit card declined"} into $users

copy-modify-return 表达式(在XQuery中也称为转换表达式,请参见本页的其他答案)提供了一种在内存中应用更改而不会丢失它们的方法,并且没有任何持久存储。它:

  • 创建一个JSON对象(作为另一个的副本)或XML节点等
  • 通过应用从修改表达式获得的PUL来修改该对象(重要的是:这没有可见的副作用,因为只修改了副本)
  • 返回修改后的副本。

对于高级用户:在这种情况下,copy子句包含构建一个新对象的构造函数,因此优化器实际上可以跳过复制。