mongodb - 检查字段是否是 MongoDB 上的字符串或文本搜索的子字符串
问题描述
需要检查该字段是否是给定输入字符串的子字符串,不敏感模式。
样本文件:
{
"_id" : ObjectId("5e6ffe413f71835ae3aa4b60"),
"f" : "Paul",
"id" : 11811,
"l" : "Green",
"r" : 64
}
如果字符串是Paul Green我想得到这个项目所以我尝试做这个查询:
db.getCollection('players').find({$or: [{'f': {'$regex': 'Paul Green', '$options': 'i'}},{'l': {'$regex': 'Paul Green', '$options': 'i'}}]})
没有结果。我也希望像pele这样的搜索会给我pelè
我怎样才能做到这一点?
解决方案
更新答案:
据我了解,您想实现搜索功能,那么您可以查看专门为文本搜索实现的 MongoDB 中的文本索引,根据我实现模糊/部分/全文/变音符号/不区分大小写文本等文本搜索的经验搜索非常有帮助。
所以我的建议是,因为您正在搜索两个字段f
-l
我建议将两个字段合并到一个字段中fl
并在其上创建一个文本索引,这样您的查询将针对一个对搜索更有效的字段,请查看以下建议:
第 1 步:如果您尚未创建合并字段,您现在可以通过 MongoDB v 上的此查询来执行此操作>=4.2
(在较低版本中,您需要找到一种方法来执行Read Coll & update field
或use aggregation + $out
):
db.collection.update({},[{$addFields : {'fl': { $concat: [ "$f", " ", "$l" ] }}}],{multi:true})
第 2 步:fl
在字段上创建文本索引:
db.collection.createIndex( { fl: "text" } )
第 3 步:您可以进行如下搜索,作为响应{fl :0}
删除字段的可选投影。fl
db.collection.find( { $text: { $search: "Paul Green" } }, {fl :0} )
注意:现在您可以获得所有文档,其中有Paulf
或Green 或 PAUL 或 GREEN 或 PAUL GREEN 或 Greèn 或 PAU 或 Pau 或 Gre 或 GRE,所以大部分都得到了整理。如果您不研究文本搜索,您仍然会研究以下方法。l
实际答案:
通常,当您想检查字符串字段中存在的输入值时 - 您会使用正则表达式来获取过滤后的文档。
但是,当您想传入一个字符串'Paul Green'
并检查一个字段是 pass'd 输入的子字符串时,普通的正则表达式对您没有帮助。但是,如果您使用的是 MongoDB 版本4.2
,您可以执行以下操作:
查询 1:
db.collection.aggregate([
/** Add a field which will be true if any of the field 'f' or 'l' is a sub-string of input (Case-insensitive) */
{
$addFields: {
result: {
$or: [
{ $regexMatch: { input: "Paul Green", regex: "$f", options: "i" } }, /** Usually input is field & regex is actual input value, we tricked it for our requirement */
{ $regexMatch: { input: "Paul Green", regex: "$l", options: "i" } }
]
}
}
},
/** Filter for all docs where result field is true (Which leave docs where 'f' or 'l' is sub-string) */
{ $match: { result: true } },
/** Remove added field result */
{ $project: { result: 0 } }
]);
测试: MongoDB-游乐场
注意:即使像发送输入字符串一样,上面的查询也可以工作,'PaulGreen'
但缺点是它不会像你想要的那样给你结果:像 pele 这样的搜索会给我 pelè,因为如果你想得到那种数据,那么您需要使用如果我们使用$regexMatch则无法使用的排序规则。因此,根据您的数据,您可以执行以下操作:
查询 2:
根据空格['Paul', 'Green']拆分字符串并传入查询:
db.collection.aggregate(
/** Filter docs if any of the word exists in any of the fields 'f' or 'l' */
[
{
$match: {
$or: [
{ f: { $in: ["Paul", "Green"] } },
{ l: { $in: ["Paul", "Green"] } }
]
}
}
],
{ collation: { locale: "fr", strength: 1 } } // Applied collation ignores case & diacritics
);
注意:以上查询可能主要使用 MongoDB 版本完成您的工作 > 3.4
,但如果您想搜索类似'PaulGreen'
的内容,则无法正常工作,由于某种原因,此查询的排序规则在 mongodb 操场上不起作用 - 请在实际数据库上进行测试。
推荐阅读
- javascript - 在 react.js 的单个父类中多次使用单个组件
- javascript - 元素顶部带有动画的生成编号
- stripe-payments - PaymentIntent 状态处理
- python - 在 python Http Requests 上渲染 reCaptcha
- javascript - Javascript 从(多行)字符串中提取唯一数组的时间太长
- php - 在此服务器上未找到请求的资源 /storage/public/user_3/1594182600.jpeg
- html - 我在 css 中使用位置标签时遇到问题
- angular - 在应用程序中使用来自 Angular 库的资源
- php - Google Sheets API,按过滤器读取值
- firebase - firebase 下载 url 未在网络上下载图像、音频和视频