使用正则表达式在 mongo 集合中搜索叶子内的字段
Searching a field inside a leaf in a mongo collection with regex
我有以下 mongo 集合,其中的记录见下面的 json 示例记录,它表示 一条 记录。例如,我的目标是搜索单词 "CONST" 并查找 "Aliases" 子树 中的 "FullName" 字段 包含该单词的记录。以显示的记录为例,它应该命中,因为 "Aliases" 树中的叶子 533-1 和 533-2 在其各自的 "FullName" 字段上包含字符串 "CONST"。例如,如果别名树仅包含树内的 533-3 叶,则它不会命中。
我使用 C# 和 MongoDb.Driver 包并使用 Regex 搜索普通字段 - 例如对于显示的此集合中的 "Key",我使用“Builders.Filter.And(filter, Builders.Filter.Regex("Key", new BsonRegularExpression("")))”模式添加条件。但是对于 "Aliases" 子树中的这些字段,我不知道如何添加条件。搜索此字段的最简单方法是什么?
请注意,在 "Aliases" 下,每片叶子都有不同的名称(533-1、533-2 等)。每片叶子的名字在整个馆藏的每条记录中都是唯一的。
记录示例:
{
"_id" : "128c5c57-ae95-4a08-9fb8-d6eade663908",
"_t" : "Company",
"ActiveFrom" : "20190813154343",
"ActiveTo" : "30001001000001",
"GroupId" : "38547478-88ef-4caf-a6ce-1a9e6a85a59b",
"Key" : "533",
"FullName" : "RED BRIGADES",
"Countries" : [
"ITALY"
],
"MoreInfo" : null,
"RecordDetail" : "<RecordDetail></RecordDetail>",
"Aliases" : {
"533-1" : {
"Key" : "533-1",
"FullName" : "BRIGADAS ROJAS PARA LA CONSTRUCCIÓN DEL PARTIDO COMUNISTA COMBATIENTE",
"OriginalKey" : "533"
},
"533-2" : {
"Key" : "533-2",
"FullName" : "BRIGADES ROUGES POUR LA CONSTRUCTION DU PARTI COMMUNISTE COMBATTANT",
"OriginalKey" : "533"
},
"533-3" : {
"Key" : "533-3",
"FullName" : "BRIGATE ROSSE",
"OriginalKey" : "533"
},
"533-4" : {
"Key" : "533-4",
"FullName" : "BRIGATE ROSSE PER LA COSTRUZIONE DEL PARTITO COMUNISTA COMBATTENTE",
"OriginalKey" : "533"
}
}
}
以下聚合管道将为您提供所需的结果。我认为尝试在 c# 中构建此管道是不值得的,因为没有 objectToArray
的构建器,而您的情况需要它。如果您的别名叶子是数组项,那么我们可以使用驱动程序的构建器构建管道。也许其他人有更好的方法。让我们看看...
db.companies.aggregate([
{
$match: {
$expr: {
$gt: [
{
$size: {
$filter: {
input: {
$objectToArray: "$Aliases"
},
as: "alias",
cond: {
$regexMatch: {
input: "$$alias.v.FullName",
regex: /CONST/
}
}
}
}
},
0
]
}
}
}
])
这可能 运行 比 查询慢,但这是可读的,您可以理解它并优化它。
db.Companies.aggregate([
// Add temporary field deconstructed_aliases to every document of collection
{
$addFields: {
deconstructed_aliases: {
$objectToArray: "$Aliases"
}
}
},
// Unwind this newly created temporary field deconstructed_aliases
{
$unwind: "$deconstructed_aliases"
},
// Match on fullName now
{
$match: {
"deconstructed_aliases.v.FullName": {
$regex: new RegExp('CONST', 'i')
}
}
},
// Project needed fields
{
$project: {
_id: 0,
key: "$deconstructed_aliases.v.Key",
fullName: "$deconstructed_aliases.v.FullName"
}
}
]);
C# 驱动程序在聚合流畅接口中似乎没有 addField 辅助方法。
此外,没有直接支持规范化对象所需的 objectToArray 运算符,因此创建魔术字符串作为解决方法。
这里有对应的C#程序-
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Testing
{
class Program
{
static void Main(string[] args)
{
MongoClient client = new MongoClient("mongodb://localhost:27017/test");
IMongoDatabase database = client.GetDatabase("test");
IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument>("Companies");
string searchTerm = "CONST";
string searchResult = FetchKeysBySearchTerm(collection, searchTerm).Result.ToJson();
Console.WriteLine(searchResult);
}
public async static Task<List<BsonDocument>> FetchKeysBySearchTerm(IMongoCollection<BsonDocument> collection, string searchTerm)
{
string addFieldStage = @"{ $addFields: { deconstructed_aliases: { $objectToArray: ""$Aliases"" } } }";
string unwindStage = @"{ $unwind: ""$deconstructed_aliases"" }";
string projectStage = @"{ $project: { _id: 0, key: ""$deconstructed_aliases.v.Key"", fullName: ""$deconstructed_aliases.v.FullName"" } }";
var aggregate = collection.Aggregate()
.AppendStage<BsonDocument>(addFieldStage)
.AppendStage<BsonDocument>(unwindStage)
.Match(Builders<BsonDocument>.Filter.Regex("deconstructed_aliases.v.FullName", new BsonRegularExpression(searchTerm, "i")))
.AppendStage<BsonDocument>(projectStage);
List<BsonDocument> searchResults = await aggregate.ToListAsync();
return searchResults;
}
}
}
这是示例响应 -
[{ "key" : "533-1", "fullName" : "BRIGADAS ROJAS PARA LA CONSTRUCCIÓN DEL PARTIDO COMUNISTA COMBATIENTE" }, { "key" : "533-2", "fullName" : "BRIGADES ROUGES POUR LA CONSTRUCTION DU PARTI COMMUNISTE COMBATTANT" }]
我有以下 mongo 集合,其中的记录见下面的 json 示例记录,它表示 一条 记录。例如,我的目标是搜索单词 "CONST" 并查找 "Aliases" 子树 中的 "FullName" 字段 包含该单词的记录。以显示的记录为例,它应该命中,因为 "Aliases" 树中的叶子 533-1 和 533-2 在其各自的 "FullName" 字段上包含字符串 "CONST"。例如,如果别名树仅包含树内的 533-3 叶,则它不会命中。
我使用 C# 和 MongoDb.Driver 包并使用 Regex 搜索普通字段 - 例如对于显示的此集合中的 "Key",我使用“Builders.Filter.And(filter, Builders.Filter.Regex("Key", new BsonRegularExpression("")))”模式添加条件。但是对于 "Aliases" 子树中的这些字段,我不知道如何添加条件。搜索此字段的最简单方法是什么?
请注意,在 "Aliases" 下,每片叶子都有不同的名称(533-1、533-2 等)。每片叶子的名字在整个馆藏的每条记录中都是唯一的。 记录示例:
{
"_id" : "128c5c57-ae95-4a08-9fb8-d6eade663908",
"_t" : "Company",
"ActiveFrom" : "20190813154343",
"ActiveTo" : "30001001000001",
"GroupId" : "38547478-88ef-4caf-a6ce-1a9e6a85a59b",
"Key" : "533",
"FullName" : "RED BRIGADES",
"Countries" : [
"ITALY"
],
"MoreInfo" : null,
"RecordDetail" : "<RecordDetail></RecordDetail>",
"Aliases" : {
"533-1" : {
"Key" : "533-1",
"FullName" : "BRIGADAS ROJAS PARA LA CONSTRUCCIÓN DEL PARTIDO COMUNISTA COMBATIENTE",
"OriginalKey" : "533"
},
"533-2" : {
"Key" : "533-2",
"FullName" : "BRIGADES ROUGES POUR LA CONSTRUCTION DU PARTI COMMUNISTE COMBATTANT",
"OriginalKey" : "533"
},
"533-3" : {
"Key" : "533-3",
"FullName" : "BRIGATE ROSSE",
"OriginalKey" : "533"
},
"533-4" : {
"Key" : "533-4",
"FullName" : "BRIGATE ROSSE PER LA COSTRUZIONE DEL PARTITO COMUNISTA COMBATTENTE",
"OriginalKey" : "533"
}
}
}
以下聚合管道将为您提供所需的结果。我认为尝试在 c# 中构建此管道是不值得的,因为没有 objectToArray
的构建器,而您的情况需要它。如果您的别名叶子是数组项,那么我们可以使用驱动程序的构建器构建管道。也许其他人有更好的方法。让我们看看...
db.companies.aggregate([
{
$match: {
$expr: {
$gt: [
{
$size: {
$filter: {
input: {
$objectToArray: "$Aliases"
},
as: "alias",
cond: {
$regexMatch: {
input: "$$alias.v.FullName",
regex: /CONST/
}
}
}
}
},
0
]
}
}
}
])
这可能 运行 比
db.Companies.aggregate([
// Add temporary field deconstructed_aliases to every document of collection
{
$addFields: {
deconstructed_aliases: {
$objectToArray: "$Aliases"
}
}
},
// Unwind this newly created temporary field deconstructed_aliases
{
$unwind: "$deconstructed_aliases"
},
// Match on fullName now
{
$match: {
"deconstructed_aliases.v.FullName": {
$regex: new RegExp('CONST', 'i')
}
}
},
// Project needed fields
{
$project: {
_id: 0,
key: "$deconstructed_aliases.v.Key",
fullName: "$deconstructed_aliases.v.FullName"
}
}
]);
C# 驱动程序在聚合流畅接口中似乎没有 addField 辅助方法。
此外,没有直接支持规范化对象所需的 objectToArray 运算符,因此创建魔术字符串作为解决方法。
这里有对应的C#程序-
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Testing
{
class Program
{
static void Main(string[] args)
{
MongoClient client = new MongoClient("mongodb://localhost:27017/test");
IMongoDatabase database = client.GetDatabase("test");
IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument>("Companies");
string searchTerm = "CONST";
string searchResult = FetchKeysBySearchTerm(collection, searchTerm).Result.ToJson();
Console.WriteLine(searchResult);
}
public async static Task<List<BsonDocument>> FetchKeysBySearchTerm(IMongoCollection<BsonDocument> collection, string searchTerm)
{
string addFieldStage = @"{ $addFields: { deconstructed_aliases: { $objectToArray: ""$Aliases"" } } }";
string unwindStage = @"{ $unwind: ""$deconstructed_aliases"" }";
string projectStage = @"{ $project: { _id: 0, key: ""$deconstructed_aliases.v.Key"", fullName: ""$deconstructed_aliases.v.FullName"" } }";
var aggregate = collection.Aggregate()
.AppendStage<BsonDocument>(addFieldStage)
.AppendStage<BsonDocument>(unwindStage)
.Match(Builders<BsonDocument>.Filter.Regex("deconstructed_aliases.v.FullName", new BsonRegularExpression(searchTerm, "i")))
.AppendStage<BsonDocument>(projectStage);
List<BsonDocument> searchResults = await aggregate.ToListAsync();
return searchResults;
}
}
}
这是示例响应 -
[{ "key" : "533-1", "fullName" : "BRIGADAS ROJAS PARA LA CONSTRUCCIÓN DEL PARTIDO COMUNISTA COMBATIENTE" }, { "key" : "533-2", "fullName" : "BRIGADES ROUGES POUR LA CONSTRUCTION DU PARTI COMMUNISTE COMBATTANT" }]