Join solr连接查询

Join solr连接查询,join,solr,Join,Solr,我需要在solr索引上运行联接查询。我已经索引了两个xml,person.xml和subject.xml 人: <doc> <field name="id">P39126</field> <field name="family">Smith</field> <field name="given">John</field> <field name="subject">S1276</field>

我需要在solr索引上运行联接查询。我已经索引了两个xml,person.xml和subject.xml

人:

<doc>
<field name="id">P39126</field>
<field name="family">Smith</field>
<field name="given">John</field>
<field name="subject">S1276</field>
<field name="subject">S1312</field>
</doc>

P39126
史密斯
约翰
S1276
S1312
主题:

<doc>
<field name="id">S1276</field>
<field name="topic">Abnormalities, Human</field>
</doc>

S1276
人类异常
我只需要显示person文档中的信息,但每个查询都应该匹配person和subject中的字段。如果查询只匹配主题文档,我需要显示具有匹配id的人员的所有文档。这是否可以不运行两个单独的查询?类似于连接查询的东西可以完成这项工作


有什么帮助吗?

我不认为使用您的模式通过一个查询就可以实现您的要求

您应该记住的一件事是始终将Solr索引视为单个非规范化表。这有时是一个挑战,有时您必须为每种数据使用不同的索引

对于您的问题,使用这样的模式可能会有所帮助:

<doc>
 <field name="id">P39126</field>
 <field name="family">Smith</field>
 <field name="given">John</field>
 <field name="topic">Abnormalities, Human</field> <!-- subject S1276 -->
 <field name="topic">some, other, topics</field> <!-- subject S1312 -->
</doc>

P39126
史密斯
约翰
人类异常
一些,其他,话题,
使用此架构运行某些主题的查询将返回所有具有这些主题的人员

您可能会感兴趣的一些链接:


我认为不可能使用您的模式通过单个查询来实现您的要求

您应该记住的一件事是始终将Solr索引视为单个非规范化表。这有时是一个挑战,有时您必须为每种数据使用不同的索引

对于您的问题,使用这样的模式可能会有所帮助:

<doc>
 <field name="id">P39126</field>
 <field name="family">Smith</field>
 <field name="given">John</field>
 <field name="topic">Abnormalities, Human</field> <!-- subject S1276 -->
 <field name="topic">some, other, topics</field> <!-- subject S1312 -->
</doc>

P39126
史密斯
约翰
人类异常
一些,其他,话题,
使用此架构运行某些主题的查询将返回所有具有这些主题的人员

您可能会感兴趣的一些链接:


如果您不能按照Pascal的建议进行反规范化,您可以编写自己的查询处理程序来执行联接:首先对请求的主题发出一个查询,请求匹配文档的id字段,然后发出一个布尔查询,每个id包含一个子句(TermQuery on subject=id)。如果有大量的id,这将有相当差的性能,但是如果只有几个匹配的id,这应该是好的

如果您预期您的“join”查询通常会匹配很多(比如数百个)主题,那么您最好按照建议进行非规范化

我不知道从处理程序发出查询的最优雅的方式,但FWIW我是这样做的

Map args = new HashMap();
// add your query parameters to the map, like fields to return
args.put("fl", new String[]{"id"});
final SolrIndexSearcher searcher = req.getSearcher();
String query = "your query"
LocalSolrQueryRequest newReq = new LocalSolrQueryRequest(core, query, "", 0, 0, args) {
  @Override public SolrIndexSearcher getSearcher() { return searcher; }
  @Override public void close() { }
};
SolrQueryResponse newRsp = new SolrQueryResponse();
core.execute(core.getRequestHandler(newReq.getParams().get(CommonParams.QT)), newReq, newRsp);
// query results will be in newRsp

如果您不能按照Pascal的建议进行反规范化,那么可以编写自己的查询处理程序来执行联接:首先对请求的主题发出一个查询,该主题请求匹配文档的id字段,然后发出一个布尔查询,每个id包含一个子句(主题=id的TermQuery)。如果有大量的id,这将有相当差的性能,但是如果只有几个匹配的id,这应该是好的

如果您预期您的“join”查询通常会匹配很多(比如数百个)主题,那么您最好按照建议进行非规范化

我不知道从处理程序发出查询的最优雅的方式,但FWIW我是这样做的

Map args = new HashMap();
// add your query parameters to the map, like fields to return
args.put("fl", new String[]{"id"});
final SolrIndexSearcher searcher = req.getSearcher();
String query = "your query"
LocalSolrQueryRequest newReq = new LocalSolrQueryRequest(core, query, "", 0, 0, args) {
  @Override public SolrIndexSearcher getSearcher() { return searcher; }
  @Override public void close() { }
};
SolrQueryResponse newRsp = new SolrQueryResponse();
core.execute(core.getRequestHandler(newReq.getParams().get(CommonParams.QT)), newReq, newRsp);
// query results will be in newRsp

看来很快就会有一个很好的连接实现:

看来很快就会有一个好的连接实现:

非常感谢帕斯卡。我真的不知道如何改变模式。我们有一些相当大的XML文件要索引(大约4个),每个文件都有自己的模式,具有相互连接的ID。使所有这些成为一个大的xml意味着大量的重复和一个巨大的xml文件。就性能而言,我不知道什么更好。做一些额外的查询,或者使用大量重复的大型xml。我倾向于说,在大多数情况下,您不应该担心重复,而应该努力使您的主实体完全非规范化。Lucene指数在这方面相当不错。在查询时,您可以始终使用fl参数来限制要返回给用户的内容。非常感谢Pascal。我真的不知道如何改变模式。我们有一些相当大的XML文件要索引(大约4个),每个文件都有自己的模式,具有相互连接的ID。使所有这些成为一个大的xml意味着大量的重复和一个巨大的xml文件。就性能而言,我不知道什么更好。做一些额外的查询,或者使用大量重复的大型xml。我倾向于说,在大多数情况下,您不应该担心重复,而应该努力使您的主实体完全非规范化。Lucene指数在这方面相当不错。在查询时,您始终可以使用fl参数来限制要返回给用户的内容。非常感谢!就我而言,我认为走这条路并不是一个真正的选择。我的数据集是巨大的,将有相当多的匹配ID,这将降低性能。我现在正在研究使用SOLR的datahandler来完成这项工作。不过,我们必须建立一个数据库。非常感谢!就我而言,我认为走这条路并不是一个真正的选择。我的数据集是巨大的,将有相当多的匹配ID,这将降低性能。我现在正在研究使用SOLR的datahandler来完成这项工作。但我们必须建立一个数据库。