检查字段是否为MongoDB上字符串或文本搜索的子字符串
需要检查字段是否是给定输入字符串的子字符串,不敏感模式 样本单据:检查字段是否为MongoDB上字符串或文本搜索的子字符串,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,需要检查字段是否是给定输入字符串的子字符串,不敏感模式 样本单据: { "_id" : ObjectId("5e6ffe413f71835ae3aa4b60"), "f" : "Paul", "id" : 11811, "l" : "Green", "r" : 64 } db.collection.aggregate([ /** Add a field which will be true if any of the field 'f' or '
{
"_id" : ObjectId("5e6ffe413f71835ae3aa4b60"),
"f" : "Paul",
"id" : 11811,
"l" : "Green",
"r" : 64
}
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 } }
]);
如果字符串为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
上的此查询进行合并(在较低版本中,您需要找到一种方法来执行读取Coll&更新字段
或使用聚合+$out
):
步骤2:在fl
字段上创建文本索引:
db.collection.createIndex( { fl: "text" } )
步骤3:您可以执行如下搜索,一个可选的投影{fl:0}
,以删除响应中的fl
字段
db.collection.find( { $text: { $search: "Paul Green" } }, {fl :0} )
注意:现在您可以获得f
或l
有保罗、格林、保罗、格林、格雷恩、保罗、保罗、保罗、格雷恩、保罗、格雷厄姆、格雷厄姆、格雷厄姆或格雷厄姆的所有文档,因此大部分文档都可以得到整理。如果您不研究文本搜索,您仍然会研究下面的方法
实际答案:
{
"_id" : ObjectId("5e6ffe413f71835ae3aa4b60"),
"f" : "Paul",
"id" : 11811,
"l" : "Green",
"r" : 64
}
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 } }
]);
通常,当您想要检查字符串字段中存在的输入值时,您会使用正则表达式来获取过滤后的文档
但是,当您想传入一个字符串“Paul Green”
&检查字段是否是pass'd输入的子字符串时,普通正则表达式对您没有帮助。但如果您使用的是MongoDB版本4.2
,您可以做以下几件事:
查询1:
{
"_id" : ObjectId("5e6ffe413f71835ae3aa4b60"),
"f" : "Paul",
"id" : 11811,
"l" : "Green",
"r" : 64
}
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 } }
]);
测试:
注意:即使发送输入字符串,如'PaulGreen'
,上述查询也会起作用,但缺点是它不会像您希望的那样为您提供结果:像pele这样的搜索会给我pelè,因为如果您想要获取此类数据,然后您需要使用排序规则,如果我们使用。因此,根据您的数据,您可以执行以下操作:
查询2:
{
"_id" : ObjectId("5e6ffe413f71835ae3aa4b60"),
"f" : "Paul",
"id" : 11811,
"l" : "Green",
"r" : 64
}
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 } }
]);
基于空格分割字符串['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 Played中不起作用-请在实际数据库中测试它。您真的必须根据f
&l
搜索“Paul Green”吗?你不能把它分成两部分&搜索字段吗?因为你的查询会检查字符串中的pass'd是字段的子字符串,但不检查字段是值中pass'd的子字符串。我必须按原样搜索。在这种情况下,有一种方法可以获取文档,但我们不能对其进行排序::pele将给我pelè
无法完成..给我部分建议和Gre(缩写)@MD10:我不知道,你想把Pau
和Gre
作为输入传递(或者)相同的输入Paul Green
你想得到字段值可以是Pau
或Gre
的文档吗?我的目标是实现这样的搜索@MD10:好的,在mongo中没有直接的方法来完成你想要的!!当您传入Paul Green
时,您无法获取带有pre
或gre
的文档,除非您拆分输入字符串并作为输入传入。你最好的选择是Query1,或者因为你正在寻找Pau
或Gre
你可以将Paul Green
拆分为['Pau'、'Paul'、'Green'、'Gre']
从代码中使用Query2
。好的,你可以拆分,请给我一些查询建议。