You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Solr在不执行全量导入时同步删除数据库已移除行对应文档?

同步Solr文档删除的解决方案

针对你的场景,核心是利用Solr Data Import Handler(DIH)的deletedQuery机制,或者通过自定义脚本实现反向比对删除,无需执行带clean标志的全量/增量导入(后者确实会清空整个索引,完全不可取)。

方案一:利用数据库删除日志表 + DIH deletedQuery(推荐)

这是最可靠且性能友好的方式,需要数据库配合记录删除操作:

  1. 在数据库中创建删除日志表
    新建一张表(比如deleted_test_view_records),用于记录每次从test_view中删除的行的x_id和删除时间:

    CREATE TABLE deleted_test_view_records (
        x_id INT PRIMARY KEY,
        deleted_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    );
    

    同时,确保数据库在删除test_view行时,自动将对应的x_id和删除时间插入该表(可以通过触发器实现)。

  2. 修改DIH配置添加deletedQuery
    在你的entity配置中新增deletedQuery参数,让DIH在增量导入时自动查询并删除Solr中对应的数据:

    <document>
        <entity name="myEntity"
                query="select * from test_view"
                deltaImportQuery="select * from test_view WHERE x_id= ${dih.delta.x_id}"
                deltaQuery="SELECT x_id from test_view where time_entered > '${dih.last_index_time}'"
                deletedQuery="SELECT x_id from deleted_test_view_records where deleted_time > '${dih.last_index_time}'"
                >
          <field column="x_id" name="id"/>
          <!-- 其他字段配置 -->
        </entity>
    </document>
    
  3. 执行增量导入的效果
    每次执行delta-import时,DIH会:

    • 先通过deltaQuery获取新增/更新的x_id,用deltaImportQuery导入对应数据
    • 同时通过deletedQuery获取上次增量后被删除的x_id,自动向Solr发送删除请求,同步删除这些ID对应的文档
    • 全程不会清空索引,只处理增量的增删改

方案二:无删除日志表时的反向比对(备选)

如果无法修改数据库创建删除日志表,可以通过定期比对数据库和Solr的ID集合来实现删除:

  1. 导出数据库当前所有有效x_id
    每隔20分钟(和增量导入同步),执行SQL导出test_view中所有x_id到临时文件:

    COPY (SELECT x_id FROM test_view) TO '/tmp/current_ids.txt';
    
  2. 获取Solr中所有索引的ID
    通过Solr的select API查询所有ID(注意分页处理,避免内存溢出):

    curl "http://your-solr-host:8983/solr/your-collection/select?q=*:*&fl=id&rows=10000&start=0" | jq -r '.response.docs[].id' > /tmp/solr_ids.txt
    
  3. 找出需要删除的ID
    使用命令行工具比对两个文件,找出存在于Solr但不在数据库中的ID:

    comm -23 <(sort /tmp/solr_ids.txt) <(sort /tmp/current_ids.txt) > /tmp/to_delete_ids.txt
    
  4. 批量删除Solr中的无效文档
    将需要删除的ID批量发送给Solr的更新API:

    # 生成JSON格式的删除请求
    echo '{"delete": {"id": [' > /tmp/delete_request.json
    paste -sd "," /tmp/to_delete_ids.txt >> /tmp/delete_request.json
    echo ']}}' >> /tmp/delete_request.json
    
    # 发送请求到Solr
    curl -X POST -H "Content-Type: application/json" http://your-solr-host:8983/solr/your-collection/update -d @/tmp/delete_request.json
    # 提交更改
    curl http://your-solr-host:8983/solr/your-collection/update -d '<commit/>'
    

    注意:此方案对性能有一定要求,若数据库规模极大,导出全量ID可能耗时,建议根据业务场景优化(比如按时间分片比对)。

关键提示

  • 绝对不要使用clean=true的增量导入,它会先清空整个Solr索引,再导入增量数据,完全不符合你的需求。
  • 方案一的触发器需要确保在删除test_view行时,无论通过什么方式删除(批量删除、单条删除),都能将x_id写入删除日志表,避免遗漏。

内容的提问来源于stack exchange,提问作者Mar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 06:35:48