MongoDB "find" - 如何查询包含字符串、不区分大小写和区分变音符号的字段的文档?
MongoDB "find" - How To Query For Docs With Field Containing a String, Case Insensitive And Diacritic Sensitive?
我正在尝试创建一个 mongo 查找查询,该查询在搜索 mongo 文档时使用字符串输入,但我找不到满足所有三个要求的语法:
当且仅当:
输入字符串包含在(或等于)字段值内。
忽略区分大小写(如果仅区别是字母的大写或小写则匹配)
变音符号敏感(输入与具有不同变音符号的字母不匹配,即对待 o 与 ö 不同)
假设我的 collection:
中有这些文件
[
{
_id: <some object id>,
title: 'home',
},
{
_id: <some other object id>,
title: 'HoMe',
},
{
_id: <some other object id>,
title: 'AllTheWayHome.',
},
{
_id: <some other object id>,
title: 'höme',
}
]
我的项目的正确实现应该return上面的所有文档除了最后一个(因为变音符号使它不匹配)。
这是我试过的...
1) 使用“正则表达式”
当创建一个新的“RegExp”object 并将其用作查询 object 时,我能够进行“包含”搜索,最后的“i”使它成为可能不区分大小写。
const query = { title: new RegExp(`.*${searchText}*.`, 'i') }
return collection.find(query).toArray();
^ 这种方法的问题是我还没有找到使它对变音符号敏感的方法。
2。使用“正则表达式”
有趣的是,如果我尝试这样做,它永远不会匹配任何文档(我希望它的工作方式与“新 RegExp”相同)。
const query = { title: /.*${searchText}*./i }
return collection.find(query).toArray();
^ 这个正则表达式似乎可以匹配任何字面意思,return 搜索所有可能的 searchText 值的文档。
3。使用“$text”和“$search”
查看 Mongo 文档后,我发现可以使用这个方便的“$text”语法,所以我尝试了这样的查询:
const query = {
$text: {
$search: searchText,
$caseSensitive: false,
$diacriticSensitive: true
}
}
return collection.find(query).toArray();
^ 然而,这个似乎没有执行我正在寻找的“包含”搜索。
(例如,“home”与“AllTheWayHome”不匹配,而它应该匹配)。
在阅读了关于这个问题的一些答案之后,我发现了一个有趣的评论,其中有很多赞成票说这个“$text,$search”语法不能“包含”搜索,句号。 (这仍然是真的吗?)
注意:我在“标题”字段上添加了文本索引,但我仍然得到完全相同的结果(仅匹配完全匹配字符串,忽略变音符号)。
no, infact text operator does not allow to execute "contains", so it
will only return exact word match, the only option currently as of 3.0
is to use regex , i.e. db.users.find( { username:/son/i } ) this one
looksup every user containing "son" (case-insenstive)
所以,总而言之,我完全感到困惑,如果有任何关于如何实现我要实现的目标的建议,我将不胜感激。
谢谢!
我尝试了第三种方法,它对我有用。
我认为您可能错过的唯一一件事是在 title
字段上添加 text index
。
来自 mongo 文档:-
$text performs a text search on the content of the fields indexed with a text index.
使用以下命令添加索引并尝试 运行 查询。
db.collection.createIndex( { title: "text" } )
编辑:-
- 这些是我试过的文件。
- 出于测试目的,我在
student
集合中插入了记录。这里是indexes
关于这个集合的截图。
- 这是查询和结果集。它包括
All the way home
并排除 höme
。
我正在尝试创建一个 mongo 查找查询,该查询在搜索 mongo 文档时使用字符串输入,但我找不到满足所有三个要求的语法:
当且仅当:
输入字符串包含在(或等于)字段值内。
忽略区分大小写(如果仅区别是字母的大写或小写则匹配)
变音符号敏感(输入与具有不同变音符号的字母不匹配,即对待 o 与 ö 不同)
假设我的 collection:
中有这些文件[
{
_id: <some object id>,
title: 'home',
},
{
_id: <some other object id>,
title: 'HoMe',
},
{
_id: <some other object id>,
title: 'AllTheWayHome.',
},
{
_id: <some other object id>,
title: 'höme',
}
]
我的项目的正确实现应该return上面的所有文档除了最后一个(因为变音符号使它不匹配)。
这是我试过的...
1) 使用“正则表达式”
当创建一个新的“RegExp”object 并将其用作查询 object 时,我能够进行“包含”搜索,最后的“i”使它成为可能不区分大小写。
const query = { title: new RegExp(`.*${searchText}*.`, 'i') }
return collection.find(query).toArray();
^ 这种方法的问题是我还没有找到使它对变音符号敏感的方法。
2。使用“正则表达式”
有趣的是,如果我尝试这样做,它永远不会匹配任何文档(我希望它的工作方式与“新 RegExp”相同)。
const query = { title: /.*${searchText}*./i }
return collection.find(query).toArray();
^ 这个正则表达式似乎可以匹配任何字面意思,return 搜索所有可能的 searchText 值的文档。
3。使用“$text”和“$search”
查看 Mongo 文档后,我发现可以使用这个方便的“$text”语法,所以我尝试了这样的查询:
const query = {
$text: {
$search: searchText,
$caseSensitive: false,
$diacriticSensitive: true
}
}
return collection.find(query).toArray();
^ 然而,这个似乎没有执行我正在寻找的“包含”搜索。 (例如,“home”与“AllTheWayHome”不匹配,而它应该匹配)。
在阅读了关于这个问题的一些答案之后,我发现了一个有趣的评论,其中有很多赞成票说这个“$text,$search”语法不能“包含”搜索,句号。 (这仍然是真的吗?)
注意:我在“标题”字段上添加了文本索引,但我仍然得到完全相同的结果(仅匹配完全匹配字符串,忽略变音符号)。
no, infact text operator does not allow to execute "contains", so it will only return exact word match, the only option currently as of 3.0 is to use regex , i.e. db.users.find( { username:/son/i } ) this one looksup every user containing "son" (case-insenstive)
所以,总而言之,我完全感到困惑,如果有任何关于如何实现我要实现的目标的建议,我将不胜感激。
谢谢!
我尝试了第三种方法,它对我有用。
我认为您可能错过的唯一一件事是在 title
字段上添加 text index
。
来自 mongo 文档:-
$text performs a text search on the content of the fields indexed with a text index.
使用以下命令添加索引并尝试 运行 查询。
db.collection.createIndex( { title: "text" } )
编辑:-
- 这些是我试过的文件。
- 出于测试目的,我在
student
集合中插入了记录。这里是indexes
关于这个集合的截图。
- 这是查询和结果集。它包括
All the way home
并排除höme
。