Golang与Solr的集成方案探讨

Golang与Solr的集成方案探讨 我正在尝试在Go语言中实现Solr搜索,但无法正确使用 github.com/vanng822/go-solr/solr 包。请帮助我了解如何使用Go语言的API将数据索引到Solr。

3 回复

我想在Go语言中实现对多列的搜索,为此我打算使用Solr搜索。我能够通过Solr的Web应用程序上传数据,但无法使用Go语言来索引数据。

更多关于Golang与Solr的集成方案探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


请帮助我们更好地帮助你:

  • 描述你试图做什么。
  • 展示你使用的代码的相关部分。
  • 你遇到任何错误了吗?展示给我们看!
  • 你期望的行为是什么?你实际观察到的行为是什么?

在Go中集成Solr进行数据索引,可以使用github.com/vanng822/go-solr/solr包。以下是一个完整的示例,展示如何连接Solr并索引文档:

package main

import (
    "fmt"
    "log"
    "github.com/vanng822/go-solr/solr"
)

func main() {
    // 创建Solr连接
    si, err := solr.NewSolrInterface("http://localhost:8983/solr", "mycore")
    if err != nil {
        log.Fatal(err)
    }

    // 准备要索引的文档数据
    docs := []solr.Document{
        {
            "id":         "1",
            "title":      "Go语言编程",
            "author":     "张三",
            "content":    "Go语言并发编程实战",
            "publish_date": "2023-10-01T10:30:00Z",
        },
        {
            "id":         "2",
            "title":      "Solr搜索引擎",
            "author":     "李四",
            "content":    "Solr分布式搜索架构",
            "publish_date": "2023-10-02T14:45:00Z",
        },
    }

    // 创建索引请求
    params := &solr.DocumentAddParams{
        Commit: true, // 提交更改
        Overwrite: true, // 覆盖已存在文档
    }

    // 执行索引操作
    resp, err := si.Add(docs, 0, params)
    if err != nil {
        log.Fatal("索引失败:", err)
    }

    if resp.Success {
        fmt.Printf("成功索引 %d 个文档\n", len(docs))
        fmt.Printf("响应状态: %d\n", resp.Status)
    } else {
        fmt.Printf("索引失败: %v\n", resp.Error)
    }

    // 查询验证
    query := solr.NewQuery()
    query.Q("*:*")
    query.Rows(10)

    s := si.Search(query)
    r, err := s.Result(nil)
    if err != nil {
        log.Fatal("查询失败:", err)
    }

    fmt.Printf("总文档数: %d\n", r.Results.NumFound)
    for _, doc := range r.Results.Docs {
        fmt.Printf("文档ID: %v, 标题: %v\n", doc["id"], doc["title"])
    }
}

对于批量索引大量数据,可以使用以下优化方案:

func batchIndex(si *solr.SolrInterface, documents []solr.Document, batchSize int) error {
    for i := 0; i < len(documents); i += batchSize {
        end := i + batchSize
        if end > len(documents) {
            end = len(documents)
        }

        batch := documents[i:end]
        params := &solr.DocumentAddParams{
            Commit: false,
            Overwrite: true,
        }

        resp, err := si.Add(batch, 0, params)
        if err != nil {
            return fmt.Errorf("批次 %d 索引失败: %v", i/batchSize, err)
        }

        if !resp.Success {
            return fmt.Errorf("批次 %d 响应错误: %v", i/batchSize, resp.Error)
        }

        fmt.Printf("已处理批次 %d: %d 个文档\n", i/batchSize, len(batch))
    }

    // 最后提交所有更改
    _, err := si.Commit()
    return err
}

处理复杂字段类型的示例:

func indexWithComplexFields() {
    si, _ := solr.NewSolrInterface("http://localhost:8983/solr", "products")
    
    docs := []solr.Document{
        {
            "id": "prod_001",
            "name": "笔记本电脑",
            "price": 5999.99,
            "stock": 50,
            "features": []string{"16GB内存", "512GB SSD", "独立显卡"},
            "specs": map[string]interface{}{
                "cpu": "Intel i7",
                "ram": "16GB",
                "storage": "512GB",
            },
            "categories": []string{"电子产品", "电脑", "办公设备"},
            "tags": []string{"高性能", "便携", "商务"},
            "timestamp": "2023-10-05T09:15:30Z",
        },
    }

    params := &solr.DocumentAddParams{
        Commit: true,
        Overwrite: true,
    }

    resp, err := si.Add(docs, 0, params)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("索引响应: %+v\n", resp)
}

错误处理和连接配置:

type SolrClient struct {
    si *solr.SolrInterface
}

func NewSolrClient(host, core string, timeout int) (*SolrClient, error) {
    si, err := solr.NewSolrInterface(host, core)
    if err != nil {
        return nil, fmt.Errorf("创建Solr连接失败: %v", err)
    }
    
    // 可以设置HTTP客户端配置
    // si.SetHTTPClient(&http.Client{Timeout: time.Duration(timeout) * time.Second})
    
    return &SolrClient{si: si}, nil
}

func (sc *SolrClient) IndexDocument(doc solr.Document) error {
    params := &solr.DocumentAddParams{
        Commit:   true,
        Overwrite: true,
    }

    resp, err := sc.si.Add([]solr.Document{doc}, 0, params)
    if err != nil {
        return fmt.Errorf("索引文档失败: %v", err)
    }

    if !resp.Success {
        return fmt.Errorf("Solr响应错误: %v", resp.Error)
    }

    return nil
}

func (sc *SolrClient) DeleteDocument(id string) error {
    resp, err := sc.si.Delete(id, nil)
    if err != nil {
        return fmt.Errorf("删除文档失败: %v", err)
    }

    if !resp.Success {
        return fmt.Errorf("Solr删除响应错误: %v", resp.Error)
    }

    _, err = sc.si.Commit()
    return err
}

这些示例展示了使用go-solr包进行基本索引操作、批量处理、复杂字段索引和错误处理的方法。确保Solr服务运行在指定地址,且core名称正确。

回到顶部