使用MongoDB C#/.NET驱动程序为不区分重音的搜索设置排序规则
我正在尝试使用MongoDB C#driver实现不区分重音的搜索,例如,当我搜索“Joao”时,它应该返回包含“João”和“Joao”(如果有)的所有结果 以下命令适用于MongoDBCompass,即,如果我对我的MongoDB集合运行它(当前仅包含带有“João”的文档,没有带有“Joao”的文档),它将返回正确的文档:使用MongoDB C#/.NET驱动程序为不区分重音的搜索设置排序规则,c#,mongodb,mongodb-.net-driver,C#,Mongodb,Mongodb .net Driver,我正在尝试使用MongoDB C#driver实现不区分重音的搜索,例如,当我搜索“Joao”时,它应该返回包含“João”和“Joao”(如果有)的所有结果 以下命令适用于MongoDBCompass,即,如果我对我的MongoDB集合运行它(当前仅包含带有“João”的文档,没有带有“Joao”的文档),它将返回正确的文档: db.profiles.find({FirstName:"Joao"}).collation({locale:"pt", str
db.profiles.find({FirstName:"Joao"}).collation({locale:"pt", strength: 1})
但是,当我尝试将其转换为C#时,它将不起作用(例如,如果我搜索“Joao”,则不会返回任何结果,仅当我搜索“João”):
输出:
[
{
name: 'profiles',
type: 'collection',
options: {},
info: {
readOnly: false,
uuid: UUID("4606f027-03b1-45e8-bf7f-6c99461db042")
},
idIndex: { v: 2, key: [Object], name: '_id_', ns: 'dev.profiles' }
}
]
这需要进行一些调查,因为关于这个问题的文档是scarse,但我想我知道发生了什么
profile.FirstName.ToLower().Contains(searchWord)
由驱动程序转换为$regex
查询
据我所见,mongodb中的正则表达式搜索不支持排序规则。因此,您不能使用正则表达式功能进行不区分重音的搜索
但是,您的需求的解决方案是创建一个文本索引
,其中包含您要搜索的所有字段,并利用该索引对您的搜索词进行区分大小写的搜索。这也是实现您需求的最有效方式
使用文本索引的一个限制是,它不允许您搜索部分匹配的单词,例如Jo
。不幸的是,mongodb全文搜索只适用于完整的单词
下面是一个测试程序(为了简洁起见,使用mongodb.entities库):
使用MongoDB.Driver;
使用MongoDB.Entities;
使用System.Threading.Tasks;
命名空间测试应用程序
{
公共类配置文件:实体
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共布尔被删除{get;set;}
公共int向导步骤{get;set;}
}
公共静态类程序
{
专用静态异步任务Main()
{
等待DB.InitAsync(“test”,“localhost”);
等待DB.Index()
.Key(p=>p.FirstName,KeyType.Text)
.Key(p=>p.LastName,KeyType.Text)
.CreateAsync();
等待新的[]{
新的ProfessionalProfile{FirstName=“João”,LastName=“Balboa”,IsDeleted=false,WizardStep=6},
新的ProfessionalProfile{FirstName=“Joao”,LastName=“Balboa”,IsDeleted=false,WizardStep=6},
}.SaveAsync();
IAggregateFluent聚合流=
DB.FluentTextSearch(
searchType:Search.Full,
搜索词:“Joao Mary John”,
区分大小写:错误,
变音识别敏感:假)
.Match(p=>!p.IsDeleted&&p.WizardStep==6);
var result=await aggregateFluent.toListSync();
}
}
}
为什么在c#code中提到了大量字段,却没有提到排序规则?我不知道是否100%得到了它,但我在最后几行定义了排序规则。您是否建议另一种方法?能否在mongo shelldb.getCollectionFos({name:'profiles})
中运行此命令,并将结果添加到您的问题中。我想知道您是否使用正确的排序规则创建了集合。使用请求的命令输出编辑了问题。虽然集合不是我自己创建的,但是否需要显式设置Mongo上的排序规则?谢谢回复。与此同时,我已经使用了驱动程序的.Text()+复合文本索引方法,但我很好奇为什么它不起作用,因为它是首选方法。我注意到,在JSON请求中使用.Contains()添加了//is,将它们替换为“<代码>{or:[{“FirstName”:/joao/is}、{“LastName”:/joao/is}、{“Description”:/joao/is}、{“Email”:/joao/is}、{“Facebook”:/joao/is}、{“Instagram”:/joao/is}、{“LinkedIn”:/joao/is}、{“Locations”:{“Locations”:{“Locations”:“{elemMatch”:{“Name”:“{:/joao/is},{“Council.Name”:/joao/is}]},IsDeleted:{“$ne”:true},“向导步骤”:6}]}yesFirstName:“joao”
进行相等匹配,而FirstName:/joao/is
进行正则表达式匹配。equality具有排序意识,而regex则没有。但是如何解释相同的请求与“FirstName”:/joão/is
在Compass中起作用呢?这是因为在这种情况下,不需要排序意识(因为存在平等,因为文档包含“João”)?
db.getCollectionInfos({ name: 'profiles' })
[
{
name: 'profiles',
type: 'collection',
options: {},
info: {
readOnly: false,
uuid: UUID("4606f027-03b1-45e8-bf7f-6c99461db042")
},
idIndex: { v: 2, key: [Object], name: '_id_', ns: 'dev.profiles' }
}
]