pojo类继承pojo类
使用传统的关系数据库,要保留您的内存中数据结构,需要使用复杂的ORM(对象关系映射)工具来处理众所周知的阻抗失配。 支持各种存储信息的下一代NoSQL数据库可以提供更简单的解决方案。 在本教程中,了解如何在MarkLogic数据库中存储和搜索POJO,而又不放弃一致性,可靠性或规模。
MarkLogic Server是一个Enterprise NoSQL数据库,支持架构可选的文档数据模型,ACID事务,安全性和实时搜索索引。 支持的文档格式包括XML,JSON,文本,甚至二进制(例如视频或PDF)。 功能包括:
速度 –针对当今IO系统进行了优化的 C ++实现。
可扩展性 –无共享分布式架构。
高可用性 –具有复制和灾难恢复功能。
最新版本添加了MarkLogic Java API,可轻松在Java应用程序中利用服务器。 对于本教程,您将下载MarkLogic Server的免费版本。 我们将通过音乐数据集研究一些典型的数据发现方案,执行查询以回答特定问题并更好地了解数据集。 为简单起见,我们将以POJO表示形式处理数据。 设置步骤包括安装MarkLogic Server,下载教程以及运行定义了几个用户并创建数据库和REST服务器的引导实用程序。
从http://developer.marklogic.com/products下载并安装最新版本的MarkLogic。 安装并启动MarkLogic后,转到基于浏览器的管理界面(位于http:// localhost:8001 / ),它将逐步引导您获取Express许可证并创建管理员用户。 (本教程假定您将在本地计算机上运行MarkLogic;如果不是这种情况,只要在本教程中看到“ localhost”,只要替换您的服务器名称即可。)
有关安装和运行MarkLogic的更多详细说明,请参阅安装MarkLogic Server 。
启动服务器后,从http://developer.marklogic.com/media/pojo-tutorial-01.zip下载教程源代码。 解压缩发行版。 您会发现一个标准的Maven源结构,例如可以在m2e中使用。 当然,如果愿意,您可以在不使用Maven的情况下使用源代码和类,方法是在src/main/java
目录下查找源代码,并在target/classes
目录下查找运行时环境。
在以下各节中,我们将仅显示源代码和输出中的重点内容。 为了充分利用本教程,您应该在IDE或编辑器中查看完整的示例,并运行示例以查看完整的输出。
要运行教程示例,您需要设置Java 6运行时环境(最好是最新的稳定发行版)。 您可以按常规方式配置CLASSPATH:
在命令行中,为教程类指定根目录,为Java API及其CLASSPATH上的lib依赖项指定jar。
在诸如Eclipse之类的IDE中,使用源目录中的教程类创建一个项目。 可以将Java API的jar及其lib依赖项添加到您的构建路径中,或者使用教程发行版中的Maven POM将这些依赖项下载到您的Maven存储库中。
本教程侧重于应用程序编程,而不是MarkLogic服务器管理。 因此,本教程提供了一个实用程序,可一步一步设置服务器环境。 在开始之前,请找到并检查tutorial.properties中的值。 默认值应正确设置。 只需确保tutorial.bootstrap_user和tutorial.bootstrap_password的值与MarkLogic服务器的管理凭据相匹配即可。 注意修改tutorial.properties附带的其他值。 要引导REST服务器的环境,请在命令行上运行以下命令:
引导教程的服务器端环境
java -cp CLASSPATH com.marklogic.client.tutorial.util.CreateDatabaseServer
或者,使用IDE执行此类的main方法。 完成后,此命令将完成以下操作:
-
创建了两个用户来运行您的应用程序。
允许rest-admin用户配置应用程序。 引导程序使用密码“
x
”设置该用户。允许其他作者用户编写和更新文档,以及执行搜索和检索文档。 还使用密码“
x
”创建了该用户。
为应用程序数据创建了一个名为“ TopSongs”的新数据库,并为保存扩展代码创建了一个“ TopSongs-modules”。
在“ TopSongs”数据库中添加了两个范围索引,以支持下面的某些搜索。
稍后,当您要设置自己的数据库,REST服务器和索引时,请转至 http:// localhost:8000 / appservices / ,单击“ 新建数据库” 按钮,选择数据库,然后单击“ 配置” 按钮。 现在,我们准备快速浏览数据集。
本教程的数据集包含从Wikipedia( http://en.wikipedia.org/wiki/Category:Lists_of_number-one_songs_in_the_United_States )中 提取的热门歌曲 。 每首歌曲都由一个以嵌套POJO建模的独立树结构描述(类似于JSON,但具有强类型)。 为了使JAXB能够处理,POJO类具有两个JAXB注释:一个在树结构的根类上,另一个在 descr
属性上。
@XmlRootElement
public class TopSong {
...
public Artist getArtist() {
...
}
@XmlAnyElement
public Element getDescr() {
...
}
}
该 descr
属性包含标记文本作为全文搜索的目标。 其他主要属性包括一位 artist
以及零个或多个 writers
, producers
, genres
和 weeks
。
教程源以XML文件提供了序列化的POJO。 除 descr
属性外,POJO是普通的Java Bean,可以从Java对象输入流或任何其他源中加载。
该 POJOWriter 示例创建一个数据库客户端和遍历序列化的POJO文件,使用JAXB编写的POJO到数据库作为单独的文档。 每个文档都有一个唯一的URI,并包含一个根对象及其从属对象。 这是压缩的源代码,重点放在重要部分上(后面的示例也是如此)。
DatabaseClient dbClient = DatabaseClientFactory.newClient(
"localhost", 8005, "rest-admin", "x", Authentication.DIGEST);
XMLDocumentManager docMgr = dbClient.newXMLDocumentManager();
JAXBContext context = JAXBContext.newInstance(TopSong.class);
JAXBHandle writeHandle = new JAXBHandle(context);
for (File songfile: inputDir.listFiles()) {
TopSong song = ... read the serialized POJO from the file ... ;
writeHandle.set(song);
docMgr.write("/topsongs/"+songfile.getName(), writeHandle);
}
dbClient.release();
每个使用该API的应用程序 在与 数据库 进行交互之前 都会创建一个 DatabaseClient, 然后再释放该客户端。 随后的示例将忽略这些陈述,而只关注新思想。
上面的示例调用 XMLDocumentManager.write() 方法将每个POJO持久保存为数据库中的文档。 该 JAXBHandle 类适应JAXB整合到API。 该API使用诸如JAXBHandle之类的适配器来集成标准内容表示形式,例如二进制InputStream,字符串和StAX XMLStreamReader。
该 POJOReader 例如通过调用 XMLDocumentManager.read() 方法来从数据库中获取一个POJO,再次使用JAXB 印证了之前的负载 。
XMLDocumentManager docMgr = dbClient.newXMLDocumentManager();
JAXBContext context = JAXBContext.newInstance(TopSong.class);
JAXBHandle readHandle = new JAXBHandle(context);
docMgr.read("/topsongs/Aretha-Franklin+Respect.xml", readHandle);
TopSong song = (TopSong) readHandle.get();
... print the properties of the POJO ...
该示例打印出POJO属性,产生以下输出:
文件:/topsongs/Aretha-Franklin+Respect.xml
标题| 尊重
艺术家| 艾瑞莎·富兰克林
作家| 奥蒂斯·雷丁
生产者| 史蒂夫·克罗珀
流派| 灵魂
周| 1967-06-03 | 1967-06-10
随后的示例将搜索这些属性和 descr
属性 的文本 。
寻找物业的价值
现在,我们准备调查热门歌曲数据集。 查看 Respect
的输出 ,我们可能想知道Otis Redding是否写过其他热门歌曲。
该 KeyValueSearcher 例如发现这里笔者元素包含精确值的所有文档 Otis Redding
。 这种搜索类似于SQL数据库的WHERE子句中的等于谓词,但是可以对各种文档结构进行操作,而不是对刚性关系表进行操作。
QueryManager queryMgr = dbClient.newQueryManager();
KeyValueQueryDefinition keyValueQry = queryMgr.newKeyValueDefinition();
keyValueQry.put(
queryMgr.newElementLocator(new Qname("writer")), "Otis Redding");
SearchHandle searchHandle = queryMgr.search(keyValueQry, new SearchHandle());
for (MatchDocumentSummary docSum: searchHandle.getMatchResults()) {
System.out.println("document: "+docSum.getUri());
for (MatchLocation docLoc: docSum.getMatchLocations()) {
System.out.println(" location: "+docLoc.getPath());
System.out.println(" matched: "+docLoc.getAllSnippetText());
}
}
所有查询都使用 QueryManager 。 (随后的示例跳过其构造。) KeyValueQueryDefinition 类指定查询条件。 QueryManager.search() 的调用 搜索数据库。 SearchHandle 将结果解析为Java结构,以反映查询匹配的文档以及每个文档中匹配的位置。 如果愿意,您还可以使用JSON或XML获取搜索结果。
该示例对匹配的文档和位置进行迭代以生成以下输出,从而回答了该问题。 奥蒂斯·雷丁(Otis Redding)创作了两首热门歌曲。
键值搜索输出
document: /topsongs/Aretha-Franklin+Respect.xml
location: /topSong/writers
matched: Otis Redding
document: /topsongs/Otis-Redding+Sittin-On-The-Dock-of-the-Bay.xml
location: /topSong/writers
matched: Otis Redding
对于JSON文档,您可以以几乎相同的方式搜索键的值。
在调查数据集时,一个问题通常会导致另一个问题。 我们可能想知道Aretha Franklin和Otis Redding是否合作过其他顶级歌曲。 我们可以从简单的字符串搜索开始。
字符串搜索表示查询条件,包括类似于Google搜索框的短语和布尔值。 您可以提示用户输入条件,但是在应用程序中指定静态条件也很方便。 就像搜索引擎一样, StringSearcher 示例可 在任何位置 匹配包含两个短语 Aretha Franklin
和 Otis Redding
文档 。
StringQueryDefinition stringQry = queryMgr.newStringDefinition();
stringQry.setCriteria(""Aretha Franklin" AND "Otis Redding"");
SearchHandle searchHandle = queryMgr.search(stringQry, new SearchHandle());
for (MatchDocumentSummary docSum: searchHandle.getMatchResults()) {
...
}
该示例与前面的示例的不同之处仅在于使用 StringQueryDefinition 指定条件。
在某些情况下,快速短语搜索就足以得到答案。 但是,在这种情况下,输出显示搜索过于笼统。
字符串搜索输出
位置:/ topSong / artist / artistId
匹配:http://en.wikipedia.org/wiki/Aretha_Franklin
位置:/ topSong / artist
匹配的:阿雷莎·富兰克林
位置:/ topSong / descr / p [1]
相匹配:……萨克斯唱片公司的歌手奥蒂斯·雷丁(Otis Redding)在1965年。
文档:/ topsongs / Jailhouse-Rock-Elvis-Presley + You-SendMe-Summertime -...
位置:/ topSong / descr / p [4]
匹配:…阿雷莎·富兰克林(Aretha Franklin),最高法院,奥蒂斯·雷丁(Otis Redding)
搜索与词组匹配,描述中提到了Aretha Franklin和Otis Redding,但这并不表示他们是否在歌曲上进行了合作。
要获得对我们问题的明确答案,我们需要将词组搜索限制为 artist
和 writer
属性。 我们使用查询选项定义约束。 查询选项指定查询的静态部分,不仅包括约束,还包括结果页面长度等。 您可以在执行搜索之前向数据库中写入查询选项,以提供查询的动态部分,包括条件,结果页码等。
ConstrainedSearcher示例将查询选项构建为Java中的数据结构:
约束的查询选项
QueryOptionsManager optMgr =
dbClient.newServerConfigManager().newQueryOptionsManager();
QueryOptionsBuilder optBldr = new QueryOptionsBuilder();
QueryOptionsHandle optHandle = new QueryOptionsHandle();
optHandle.withConstraints(
optBldr.constraint("artist",
optBldr.elementQuery(new QName("artistName"))),
optBldr.constraint("writer",
optBldr.elementQuery(new QName("writer"))));
optMgr.writeOptions("constraints", optHandle);
如您所料,API提供了一个 QueryOptionsManager 来编写,读取和删除查询选项。 要将选项构建为Java结构,请使用 QueryOptionsBuilder 和 QueryOptionsHandle 。 特别是,对 QueryOptionsHandle.withConstraints() 的调用 指定了对 artist
和 writer
属性的 约束 。 这样就可以将搜索短语限制为这些属性(类似于之前显示的键值搜索)。 该 QueryOptionsManager.writeOptions() 调用保存在名称查询选项 constraints
。
顺便说一下,由于查询选项通常是由经验丰富的开发人员设置的,并由其他开发人员在应用程序中使用的,因此编写它们需要更高级别的权限。 尽管我们将展示如何在Java中构建查询选项,但您也可以根据需要将查询选项编写为JSON或XML文档。
现在,我们可以使用查询选项在搜索与短语匹配的地方约束POJO属性。 该 ConstrainedSearcher 例子指定 constraints
构建 StringQueryDefinition 对象 时查询选项 ,然后在前缀 Aretha Franklin
短语与 artist
约束和 Otis Redding
短语与 writer
约束。
StringQueryDefinition stringQry = queryMgr.newStringDefinition("constraints");
stringQry.setCriteria(
"artist:"Aretha Franklin" AND writer:"Otis Redding"");
SearchHandle searchHandle = queryMgr.search(stringQry, new SearchHandle());
for (MatchDocumentSummary docSum: searchHandle.getMatchResults()) {
...
}
除了添加查询选项和约束前缀之外,此示例与以前的版本相同。 但是,结果输出要精确得多:
约束搜索输出
文件:/topsongs/Aretha-Franklin+Respect.xml
位置:/ topSong / artist
匹配的:阿雷莎·富兰克林
位置:/ topSong / writers
匹配的:Otis Redding
艺术家和作家的结合只有一首歌,这给出了我们明确的答案。
您可能会不时地以编程方式修改或检查条件。 示例包括为搜索条件提供GUI编辑器,添加隐藏条件,检查无效或未经授权的条件或生成反映外部资源当前状态的条件。
与查询选项一样,您可以使用构建器来创建Java结构。 StructuredSearcher示例为与上一示例表示为字符串相同的约束条件构建结构化搜索。
结构化搜索
StructuredQueryBuilder structureBldr =
queryMgr.newStructuredQueryBuilder("constraints");
StructuredQueryDefinition structuredQry =
structureBldr.and(
structureBldr.elementConstraint("artist",
structureBldr.term("Aretha Franklin")),
structureBldr.elementConstraint("writer",
structureBldr.term("Otis Redding")));
SearchHandle searchHandle = queryMgr.search(structuredQry, new SearchHandle());
for (MatchDocumentSummary docSum: searchHandle.getMatchResults()) {
...
}
该示例使用StructuredQueryBuilder创建一个StructuredQueryDefinition ,它为由约束查询选项定义的艺术家和作家约束指定条件。 除了使用StructuredQueryDefinition代替StringQueryDefinition之外,此示例与前面的示例相同,限定了相同的文档,并产生了相同的输出。 但是,Java程序无需更改字符串即可轻松更改其中一项或添加新的复杂布尔条件。
如果愿意,还可以将结构化查询编写为JSON或XML文档。 虽然本教程的其余部分将坚持使用字符串查询来保持一致性,但在每种情况下,都可以使用结构化查询来指定搜索条件。
到目前为止,这些示例已经回答了特定的问题。 为了帮助提出问题,获得数据集的广泛概述也很有用。 构面分析通过对整个数据集或感兴趣的子集执行计数或其他聚合来满足该要求。 下一个示例支持按类型或按时间进行方面分析。
在本教程开始时导入包时,导入操作将配置热门歌曲数据库。 配置在类型和星期元素上创建了范围索引。 范围索引为计算构面提供了基础。 现在,我们准备好利用这些类型和星期范围索引。
与上一个示例中的艺术家和作家索引一样, FacettedSearcher示例为查询选项中的类型索引和星期索引创建约束。 约束标识范围索引及其数据类型。 该示例按流派中歌曲数的降序对流派进行排序。
构面的查询选项
optHandle.withConstraints(
optBldr.constraint("genre",
optBldr.range(
optBldr.elementRangeIndex(
new QName("genre"),
optBldr.stringRangeType(
"http://marklogic.com/collation/")),
Facets.FACETED,
FragmentScope.DOCUMENTS,
null,
"frequency-order", "descending")),
optBldr.constraint("week",
optBldr.range(
optBldr.elementRangeIndex(
new QName("week"),
optBldr.rangeType("xs:date")))));
optHandle.setReturnResults(false);
optMgr.writeOptions("facetsongs", optHandle);
源代码片段跳过了QueryOptionsBuilder和QueryOptionsHandle构建器的构造,该构造与前面的示例相同。 调用QueryOptionsHandle.setReturnResults()会修改搜索,以仅返回构面分析,而不返回搜索结果页面。
facetsongs查询选项已经完成了定义方面的繁重工作。 FacettedSearcher示例在构造字符串定义时指定facetsongs查询选项。 该示例对文档中任何位置包含Grammy
术语的歌曲子集执行构面分析。 搜索可以对较小的子集使用复杂的布尔值,或者对整个数据集不使用任何条件。
方面搜索
StringQueryDefinition stringQry = queryMgr.newStringDefinition("facetsongs");
stringQry.setCriteria("Grammy");
SearchHandle searchHandle = queryMgr.search(stringQry, new SearchHandle());
for (FacetResult facet: searchHandle.getFacetResults()) {
System.out.println("facet: "+facet.getName());
for (FacetValue value: facet.getFacetValues()) {
System.out.println(" "+value.getLabel()+" = "+value.getCount());
}
}
与搜索结果一样, SearchHandle将构面列表解析为具有值及其合计计数的Java结构。 您也可以将构面读取为JSON或XML。
该示例输出分析了所有带有Grammy
词的歌曲的流派和星期。
构面输出
方面:类型
流行= 79
R&B = 71
…
节奏蓝调= 2
…
方面:星期
1940-07-27 = 1
1940-08-03 = 1
1940-08-10 = 1
…
输出显示,合并诸如R&B
和Rhythm And Blues
类的体裁值将提高数据集的质量。 很好,可以从现实世界的大数据中获得预期。 清除这些瑕疵不会改变全局,因此我们可以立即从数据集中获取价值。 如果以后的应用程序可以从修复这些缺陷中受益,则方面分析已向我们展示了修复方法。 我们可以在不妨碍现有应用程序的情况下就地优化数据集。 这种灵活,渐进的改进不同于传统的数据库,在传统的数据库中,数据结构和关联的更改会对应用程序造成破坏性影响。
出于某些目的,构面分析提供了太多的细节。 为了获得数据集的快速摘要,您可能需要汇总值范围并消除异常值。
查询选项可以限制构面值的数量。 当构面值按降序排列时,效果是返回最高值。 查询选项还可以定义用于分组构面值的存储桶。 BuckettedSearcher示例优化了先前的查询选项以添加限制和存储桶:
限制和存储桶的查询选项
optHandle.withConstraints(
optBldr.constraint("genre",
optBldr.range(
optBldr.elementRangeIndex(
new QName("genre"),
optBldr.stringRangeType(
"http://marklogic.com/collation/")),
Facets.FACETED,
FragmentScope.DOCUMENTS,
null,
"frequency-order", "descending", "limit=10")),
optBldr.constraint("week",
optBldr.range(
optBldr.elementRangeIndex(
new QName("week"),
optBldr.rangeType("xs:date")),
Facets.FACETED,
FragmentScope.DOCUMENTS,
optBldr.buckets(
optBldr.bucket("1940s", "40s", "1940-01-01", "1950-01-01"),
optBldr.bucket("1950s", "50s", "1950-01-01", "1960-01-01"),
...,
optBldr.bucket("2000s", "00s", "2000-01-01", "2010-01-01")
))));
除了引用修改后的查询选项外, BuckettedSearcher示例与上一个示例具有完全相同的搜索代码。 但是,由于查询选项的更改,该示例仅产生了顶级流派,并且按十年而不是按星期对歌曲进行分组。
构面输出限制和存储桶
方面:类型
流行= 79
R&B = 71
…
国家= 8
方面:星期
40秒= 4
50秒= 11
…
00秒= 67
通过构面分析获得的数据集维度的广泛理解可以构成对特定问题的调查。 了解歌曲数据集的流派表明,如果我们想调查昆西·琼斯职业生涯的广度,我们可以查看他所创作歌曲的流派。 可以基于范围索引快速回答此类问题。
首先, ValuesLister示例定义了生产者约束(非常类似于上一个示例中的artist和writer约束)。 查询选项还标识提供值列表(在这种情况下为流派值)的范围索引。
值的查询选项
optHandle.withConstraints(
optBldr.constraint("producer",
optBldr.elementQuery(new QName("producer")) ));
optHandle.withValues(
optBldr.values("genre",
optBldr.range(
optBldr.elementRangeIndex(
new QName("genre"),
optBldr.stringRangeType(
"http://marklogic.com/collation/" )))));
optMgr.writeOptions("valuesongs", optHandle);
为了查询值, ValuesLister示例构造了一个ValuesDefinition ,其中包含在查询选项( valuesongs
)中指定的值列表( genre
)的名称。 该示例还构造了一个StringQueryDefinition ,在Quincy Jones
添加了producer
约束(与之前的Aretha Franklin
和artist
约束一样),并使用StringQueryDefinition初始化ValuesDefinition以将值列表约束到由Quincy Jones产生的歌曲。
值清单
ValuesDefinition valdef = queryMgr.newValuesDefinition("genre", "valuesongs");
StringQueryDefinition stringQry = queryMgr.newStringDefinition();
stringQry.setCriteria("producer:"Quincy Jones"");
valdef.setQueryDefinition(stringQry);
ValuesHandle genreHandle = queryMgr.values(valdef, new ValuesHandle());
for (CountedDistinctValue value: genreHandle.getValues()) {
System.out.println(
" "+value.getCount()+" "+value.get("xs:string", String.class));
}
调用QueryManager.values()将读取索引,然后ValuesHandle将列表解析为一个Java结构,该结构反映了受约束子集的值。 这类似于之前示例中带有SearchHandle的search()方法,但是在这种情况下,直接从索引读取。 与其他地方一样,您还可以将值列表获取为JSON或XML。 该示例遍历列表以获取每个计数和值。
输出显示Quincy Jones产生了令人惊讶的热门歌曲:
值输出
制片人昆西·琼斯的热门歌曲:
1个国家灵魂
1舞
…
1华丽金属
2硬石
1爵士
…
1西海岸嘻哈
热门歌曲在一个或多个星期内很流行,可以分为一种或多种类型; 因此,每首热门歌曲都将周与流派联系在一起。 这些星期和流派的关联(称为共现,或从数据库中读取时称为元组)可以证明流派随时间的趋势。 例如,我们可以调查Quincy Jones制作的歌曲的趋势。
在查询选项中,生产者约束与前面的示例相同(因此不包含在下面的片段中)。 TuplesLister示例在一周和流派范围索引上构建week-genre
元组列表(而不是一个范围索引的值列表)。
元组的查询选项
optHandle.withTuples(
optBldr.tuples("week-genre",
optBldr.tupleSources(
optBldr.range(
optBldr.elementRangeIndex(
new QName("week"),
optBldr.rangeType("xs:date"))),
optBldr.range(
optBldr.elementRangeIndex(
new QName("genre"),
optBldr.stringRangeType(
"http://marklogic.com/collation/"))))));
optMgr.writeOptions("tuplesongs", optHandle);
要查询元组, TuplesLister示例构造一个ValuesDefinition ,其名称带有在查询选项( tuplesongs
)中指定的元组列表的名称( weeks-genre
)。 该示例将查询限制为由Quincy Jones产生的歌曲,该歌曲具有与上一个示例相同的StringQueryDefinition(因此,在下面的片段中不包括那些语句)。
元组列表
ValuesDefinition valdef =
queryMgr.newValuesDefinition("week-genre", "tuplesongs");
...
valdef.setQueryDefinition(stringQry);
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
TuplesHandle tuplesHandle = queryMgr.tuples(valdef, new TuplesHandle());
for (Tuple tuple: tuplesHandle.getTuples()) {
System.out.print(" "+tuple.getCount()+" ");
for (TypedDistinctValue value: tuple.getValues()) {
String type = value.getType();
if ("xs:date".equals(type)) {
System.out.print(dateFormat.format(
value.get(Calendar.class).getTime()));
} else if ("xs:string".equals(type)) {
System.out.print(value.get(String.class));
}
}
System.out.println();
}
调用QueryManager.tuples()将读取索引,并且TuplesHandle将元组解析为Java结构,该结构反映了受约束子集的值。 该示例遍历元组以获取每个值,并使用Java DateFormat格式化数周的日期值。
输出结果表明昆西·琼斯从制作乡村灵魂/ R&B歌曲开始并通过其他流派过渡到嘻哈音乐,从而满足了调查的目标。
元组输出
制片人昆西·琼斯(Quincy Jones)每周热门歌曲流派:
1 1962-06-02国家灵魂
1 1962-06-02 R&B
…
1 1996-07-13西海岸嘻哈
1 1996-07-20西海岸嘻哈
本教程简要概述了如何使用Java API在MarkLogic Server中保留和查询POJO。 特别是,您学习了如何:
将POJO写入数据库并从数据库读取POJO。
搜索具有键值,字符串或结构化条件的持久化POJO。
指定布尔值,全文或受元素限制的条件。
对POJO属性(包括存储桶)执行构面分析。
从索引中提取POJO属性值和元组。
MarkLogic Java API可以与POJO之外的其他内容一起使用。 您可以对具有收集,权限和属性元数据的二进制文件(包括PDF和视频),JSON,XML和文本文档执行CRUD操作。 您可以对CRUD操作使用多语句事务和乐观锁定控制。 在搜索中,您可以利用地理空间搜索和构面,索引上的聚合功能(包括用户定义的聚合)以及搜索结果的灵活摘要和元素提取。 最后,您可以使用服务器端转换和新的资源服务来扩展API。
MarkLogic Server在一个教程中有太多的功能需要探索,包括Hadoop集成,反向查询和警报,服务器端内容处理管道(用于转换,扩充或元数据提取),灵活的复制以及摄取和监视工具。 大型公司和政府机构多年来一直在关键任务解决方案中使用MarkLogic Server。 无论是为企业解决方案评估NoSQL平台,还是要通过Express许可证快速部署实现自己的好主意,都可以在http://developer.marklogic.com上了解更多信息。
快速下载– http://developer.marklogic.com/express
Java API的综合教程– http://developer.marklogic.com/learn/java
文档– http://developer.marklogic.com/docs
有关本教程的将来更新,请访问http://developer.marklogic.com/learn/java-pojos
约束:如何使用索引来限定文档的名称和规范。
构面:一种枚举或定量属性,可用于选择或分组搜索中的对象或文档。
键值搜索:查询条件,表示为属性的值。
QName:一个限定名称,为了方便起见,可以与名称空间关联,并为名称空间URI与短前缀关联。
查询选项:查询的不变部分,包括指定索引名称和使用,结果页大小等的约束。
范围索引:支持构面查询的索引(基于值查找文档或基于文档的值)。
字符串搜索:查询条件表示为简单的类似Google的表达式,带有布尔值,约束条件等。
结构化搜索:查询条件表示为具有布尔值,约束等的数据结构
值:索引中的部分或全部条目。
元组:基于文档中值同时出现的记录。
有关本教程的更新和将来的修订,请访问http://developer.marklogic.com/learn/java-pojos
翻译自: https://jaxenter.com/writing-and-searching-for-pojos-in-marklogic-104939.html
pojo类继承pojo类