1

背景:

我正在开发一个使用 Mongo 作为数据库的开源 side-project-for-fun。该项目应该是一个“存储库目录”

它应该收集有关数百/数千个软件项目的数据 - 基本信息,例如名称、描述、一些标签以及其中的文件列表。下面的示例文档。

要求:

拥有目录的主要目的是它可以轻松可靠地搜索,并且还应该依赖“部分匹配”。
因此,例如,如果一个项目名为“XmlValidator”,我应该能够通过“Xml”搜索字符串找到它。
如果一个项目包含一个名为“GoogleDriveSynchronizer.cs”的文件,我应该能够通过“Google”或“GoogleDrive”等找到它。
这不是开箱即用的。

搜索也应该很快。
在大小方面,实际上,我不希望超过 10000 个文档,平均文档大小为 2kb,但假设我希望它即使在平均大小为 3kb 的 100k 文档中也能表现良好。由于性能原因,我不考虑正则表达式搜索(虽然我不确定,也许 3KB 的 100k 文档不难扫描?)

现在的情况:

我的文本索引目前设置如下(几乎大部分字段,但不是全部):

IndexKeysDefinition<ProjectInfo> keys = Builders<ProjectInfo>.IndexKeys
                .Text(x => x.ProjectName)
                .Text(x => x.ProjectDescription)
                .Text(x => x.AssemblyName)
                .Text(x => x.ProjectUri)
                .Text(x=>x.Tags)
                .Text($"{nameof(ProjectInfo.Properties)}.{nameof(Property.Value)}")
                .Text($"{nameof(ProjectInfo.Components)}.{nameof(ComponentManifest.Name)}")
                .Text($"{nameof(ProjectInfo.Components)}.{nameof(ComponentManifest.Description)}")
                .Text($"{nameof(ProjectInfo.Components)}.{nameof(ComponentManifest.DocumentationUri)}")
                .Text($"{nameof(ProjectInfo.Components)}.{nameof(ComponentManifest.Tags)}")
                ;

样本文件

       "_id": {
            "$oid": "5e67ce562ee2d4d141822a17"
        },
        "AddedDateTime": {
            "$date": {
                "$numberLong": "1583861334692"
            }
        },
        "ProjectName": "XmlValidatorFake",
        "Autogenerated": false,
        "Owner": null,
        "ProjectDescription": null,
        "ProjectUri": null,
        "DocumentationUri": null,
        "DownloadLocation": null,
        "AssemblyName": null,
        "OutputType": null,
        "TargetExtension": null,
        "RepositoryId": {
            "$oid": "5e67ce558d980a7b344dac5f"
        },
        "RepositoryStamp": "2020-03-10T17:28:54.8444190Z",
        "Tags": [],
        "Properties": [{
            "Key": "Files", 
//the value will more often be a normal string, but could be a collection as well


  "Value": {
            "_t": "System.Collections.Generic.List`1[System.String]",
            "_v": ["FileNumberOne.cs", "FileNumberTwo.cs"]
        }
    }],
    "Components": []
}

问题/解决方案的想法:

因此,我的想法是在文档上创建另一个字段,将我认为应该可以创建的所有“令牌”放入其中。
因此,所有相关字段中的所有字符串都将被标记化(按 PascalCase、连字符、下划线等拆分)并存储在该字段中(例如 search_data)。

然后我会创建一个不同的文本索引,它只会查看 search_data 字段。

考虑因素是:

  1. 这将使文档大两倍(几乎所有数据都将在 search_data 字段中重复)
  2. 我无法为标记分配权重...除非我创建多个具有不同权重的 search_data 字段(其中将包含按相关性分组的标记化值)
  3. 如果无法对值进行标记,它仍然无法解决问题,例如,如果文件名称为“stackoverflowhackingattempt.cs”,它将不会被标记并且无法通过“hack”查询找到 - 除非它是正则表达式搜索.

这种方法有意义吗?
此外,使用这种方法,正则表达式搜索是否应该比我目前的搜索执行得更快?在我继续重新设计整个事情之前,我想知道你们的想法。
干杯!

4

0 回答 0