首页 > 解决方案 > SOLR 加入 3 个流

问题描述

试图将 3 个表中的数据合并到 1 个表中,ala 关系数据库连接。加入 2 个 SOLR 流有效。但是如何包含第三个流?

顺便提一句。这需要处理数百万行。这是一个合适的方法吗?希望所有数据都不需要加载到内存中。目标是在 solr 中进行大部分处理,而在应用程序中进行更少的处理。

第 1 部分作品:

innerJoin(
        select(
            search(dbv-database-49461a12-8b70-41f0-b5c4-c9b6c84cb5b0,q=tableId:*elevkarakter AND col1_l:166, fl="col0_l,col1_l,col2_t,col4_t,col3_l", sort="col3_l asc"),
            col1_l as elevar,
            col2_t as Termin,
            col4_t as Karakter,
            col3_l as FagkarakterId_fk),
        select(
            search(dbv-database-49461a12-8b70-41f0-b5c4-c9b6c84cb5b0,q=tableId:*fagkarakter, fl="col0_l,col1_l", sort="col0_l asc"),
            col0_l as FagkarakterId,
            col1_l as FagId),       
        on="FagkarakterId=FagkarakterId_fk"
    )

第 2 部分作品:

select(
    search(dbv-database-49461a12-8b70-41f0-b5c4-c9b6c84cb5b0,q=tableId:*fag, fl="col0_l, col5_t", sort="col0_l asc"),
    col0_l as FagId,
    col5_t as fag
)

我可以加入第 1 部分和第 2 部分做这样的事情吗?

innerJoin(
    select(
        search(dbv-database-49461a12-8b70-41f0-b5c4-c9b6c84cb5b0,q=tableId:*fag, fl="col0_l, col5_t", sort="col0_l asc"),
        col0_l as FagId,
        col5_t as fag),
    innerJoin(
            select(
                search(dbv-database-49461a12-8b70-41f0-b5c4-c9b6c84cb5b0,q=tableId:*elevkarakter AND col1_l:166, fl="col0_l,col1_l,col2_t,col4_t,col3_l", sort="col3_l asc"),
                col1_l as elevar,
                col2_t as Termin,
                col4_t as Karakter,
                col3_l as FagkarakterId),
            select(
                search(dbv-database-49461a12-8b70-41f0-b5c4-c9b6c84cb5b0,q=tableId:*fagkarakter, fl="col0_l,col1_l", sort="col0_l asc"),
                col0_l as FagkarakterId,
                col1_l as FagId),       
            on="FagkarakterId"
    ),
    on="FagId"
)

到目前为止的结果:

"EXCEPTION": "Invalid JoinStream - all incoming stream comparators (sort) must be a superset of this stream's equalitor."

标签: solr

解决方案


连接需要双方按相同的键排序,因此在您返回的连接中,情况并非如此 - 因为它是排序的,FagkarakterId而不是排序的FagId。将这些流视为一个文档流,其中左侧流前面的每个文档都被消耗,同时检查另一个流中的前面文档是否与连接条件匹配:

对于左侧流中的每个文档,检查位于头部的文档是否right匹配。给定两个流,左和右:

left         right
----         -----
foo          foo
bar          foo
baz          baz

left.pop() -> foo; 

while right.head == foo:
    # pops the next two documents in right

left         right
----         -----
bar          baz
baz          

left.pop -> bar

.. nothing matches in right

left         right
----         -----
baz          baz

left.pop -> baz

while right.head == baz:
    # pops the next document in right

您可以看到此合并策略如何要求两个流按您要加入的相同值进行排序。

据我所知,如果您必须对其中一个流重新排序,Solr 必须将整个集合保存在内存中(因为它必须读取流直到结束,然后对文档进行排序)。如果您可以仅通过源本身的文档序列来解决它,那么效率会高得多。

另一种解决方案是在索引时进行合并;生成统计信息等会更容易。


推荐阅读