将一对多数据添加到 Lucene 索引

杰森

我是 Lucene 的新手。我正在尝试创建记录索引。到目前为止,我只是将一对一的数据添加到我的索引中,这看起来很好。但是,我有需要添加一对多关系数据的场景,我不确定处理这个问题的最佳方法是什么。我曾尝试添加每个单独的关系,将字段压缩为 CSV 值,多次添加该字段,但似乎没有任何效果。这是我对数据进行索引时的代码:

Private Shared Sub _addToLuceneIndex(ByVal sampleData As LuceneSearchData, ByVal writer As IndexWriter)
    Dim searchQuery = New TermQuery(New Term("Id", sampleData.Id.ToString()))
    writer.DeleteDocuments(searchQuery)
    Dim doc = New Document()

    doc.Add(New Field("Id", sampleData.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED))
    doc.Add(New Field("Name", sampleData.Name, Field.Store.YES, Field.Index.ANALYZED))
    doc.Add(New Field("Description", sampleData.Description, Field.Store.YES, Field.Index.ANALYZED))

    For Each item As Integer In sampleData.HomeStates 
        doc.Add(New Field("Home_State", item, Field.Store.YES, Field.Index.ANALYZED))
    Next
   'i have also tried
'doc.Add(New Field("HomeStates ", String.Join(",", sampleData.HomeStates ), Field.Store.YES, Field.Index.ANALYZED))

    writer.AddDocument(doc)
End Sub

虽然上面的代码似乎索引了一对一的数据,但它不适用于 HomeStates 整数列表。我是否必须为整数列表中的每个项目添加相同的文档?如果是这样,你如何最好地管理这个?我需要包含几个“一对多”关系。我可以看到这很快变得笨拙。或者,还有更好的方法?

编辑我更新添加一个可能值作为这样的字段:

 doc.Add(New Field("Geo_Locations", String.Join(" ", sampleData.Geo_Location), Field.Store.YES, Field.Index.ANALYZED))

这就是我搜索该字段的方式:

Private Shared Function _search(ByVal searchQuery As String, ByVal Optional searchField As String = "") As IEnumerable(Of LuceneSearchData)
    If String.IsNullOrEmpty(searchQuery.Replace("*", "").Replace("?", "")) Then Return New List(Of LuceneSearchData)()

    Using searcher = New IndexSearcher(_directory, False)
        Dim hits_limit = 1000
        Dim analyzer = New StandardAnalyzer(Version.LUCENE_30)

        If Not String.IsNullOrEmpty(searchField) Then
            Dim parser = New QueryParser(Version.LUCENE_30, searchField, analyzer)
            Dim query = parseQuery(searchQuery, parser)
            Dim hits = searcher.Search(query, hits_limit).ScoreDocs
            Dim results = _mapLuceneToDataList(hits, searcher)
            analyzer.Close()
            searcher.Dispose()
            Return results
        End If
    End Using
End Function

Private Shared Function _mapLuceneToDataList(ByVal hits As IEnumerable(Of ScoreDoc), ByVal searcher As IndexSearcher) As IEnumerable(Of LuceneSearchData)
    Dim listOfResults As List(Of LuceneSearchData)

    Try
        listOfResults = hits.[Select](Function(hit) _mapLuceneDocumentToData(searcher.Doc(hit.Doc))).ToList()            
    Catch ex As Exception
        Return Nothing
    End Try
    Return listOfResults
End Function

Private Shared Function _mapLuceneDocumentToData(ByVal doc As Document) As LuceneSearchData

    Return New LuceneSearchData With {
        .Id = Convert.ToInt32(doc.[Get]("Id")),
        .Mechanism_Name = doc.[Get]("Name"),
        .Mechanism_Purpose = doc.[Get]("Description"),            
        .Geo_Location = doc.[Get]("Home_State")
    }
End Function

然后我打电话给搜索bu:

   LuceneData = LuceneSearch.Search("5451", "HomeStates")
香港

在搜索其他字段时,为每个项目创建一个新文档将导致重复。

您应该根据需要设计文档和字段。

如果您不需要搜索这些字段,请根据需要存储它们。

如果您需要搜索这些多值字段,则创建一个可以为每个项目搜索的字段。对于整数列表,您可以将它们与空格合并。对于字符串列表,您应该在索引和搜索时用一些自定义字符替换空格以避免匹配子字符串(例如“堆栈溢出”=> stack_overflow)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章