MongoDB中的搜索范围,需要子元素,而不是整个文档
我有结构相当复杂的MongoDB文档: 顶级组织(一个要素) 许多有趣的属性包括创始人和经理 创始人-创始人列表,每个人都有姓、名、赞助人(和其他属性) 与管理者相同-具有lastname、firstname、patonym(和其他属性)的元素列表 我想通过lastname+firstname+patronym组合搜索一个查询。 查询应支持多个姓、名、赞助人(在$in的帮助下)(这适用于一个人的不同姓名,即jon、john、johny) 我当前的代码返回组织内部的lastname+firstname+patronym组合,但我需要lastname+firstname+patronym组合。可能吗?即使是正确的方向,而不是代码,我也会心存感激。据我所知,$elemMatch对我没有帮助,或者这将是一个非常麻烦的查询?也许确实存在一些更干净的选择 我已经试着改变了MongoDB中的搜索范围,需要子元素,而不是整个文档,mongodb,mongodb-query,Mongodb,Mongodb Query,我有结构相当复杂的MongoDB文档: 顶级组织(一个要素) 许多有趣的属性包括创始人和经理 创始人-创始人列表,每个人都有姓、名、赞助人(和其他属性) 与管理者相同-具有lastname、firstname、patonym(和其他属性)的元素列表 我想通过lastname+firstname+patronym组合搜索一个查询。 查询应支持多个姓、名、赞助人(在$in的帮助下)(这适用于一个人的不同姓名,即jon、john、johny) 我当前的代码返回组织内部的lastname+firstna
List<BasicDBObject> args
并用append填充它。没有什么变化
我的代码:
List<BasicDBObject> args = new ArrayList<>();
args.add(new BasicDBObject("founders.typeperson.person.lastname", new BasicDBObject("$in", request.getLastnames())));
args.add(new BasicDBObject("founders.typeperson.person.firstname", new BasicDBObject("$in", request.getFirstnames())));
args.add(new BasicDBObject("founders.typeperson.person.patronym", new BasicDBObject("$in", request.getPatronyms())));
argsListUL.add(new BasicDBObject("$and", args));
result = collection.find(new BasicDBObject("$or", argsListUL)).into(new ArrayList<Document>());
获取0个结果。而数据库中存在lastname+firstname+patronym的组合
另一个注意事项:数据库的大小是500GB,所以我认为$elemMatch的投影速度太慢了 可能您应该尝试共享您的数据库方案。您的问题中不清楚您的数据库方案 据我所知,您的数据结构如下。如果结构或需求有任何不同,我会更新答案
{
"_id": ObjectId(''),
"organization": "x",
founders: [
{
lastname: 'a'
firstname: 'a',
patronym: 'a'
},
{
lastname: 'b'
firstname: 'b',
patronym: 'b'
}
],
managers: [
{
{
lastname: 'c'
firstname: 'c',
patronym: 'c'
},
{
lastname: 'd'
firstname: 'd',
patronym: 'd'
}
}
]
}
我可以建议您研究聚合管道
可用于仅获取子文档的查询为:-
db.collection.aggregate([{
$match: {
'organization': '<name>'
}
}, {
$unwind: '$managers'
}, {
$unwind: '$founders'
}, {
$match: {
$or: [{
$or: [{
"managers.lastname": {
$regex: 'searchString',
$options: 'i'
}
}, {
"managers.firstname": {
$regex: 'searchString',
$options: 'i'
}
}, {
"managers.patronym": {
$regex: 'searchString',
$options: 'i'
}
}]
}, {
$or: [{
"founders.lastname": {
$regex: 'searchString',
$options: 'i'
}
}, {
"founders.firstname": {
$regex: 'searchString',
$options: 'i'
}
}, {
"founders.patronym": {
$regex: 'searchString',
$options: 'i'
}
}]
}]
}
}, {
$group: {
"_id": {
"_id": "$_id",
"organization": "$organization",
},
"founders": {
"$push": '$founders'
},
"managers": {
"$push": '$managers'
}
}
}, {
$project: {
"_id": 0,
"founders": 1,
"managers" 1
}
}])
db.collection.aggregate([{
$match:{
“组织”:“
}
}, {
$unwind:“$managers”
}, {
$unwind:“$founders”
}, {
$match:{
$or:[{
$or:[{
“managers.lastname”:{
$regex:'searchString',
$options:“我”
}
}, {
“经理.名字”:{
$regex:'searchString',
$options:“我”
}
}, {
“经理.赞助人”:{
$regex:'searchString',
$options:“我”
}
}]
}, {
$or:[{
“创始人.姓氏”:{
$regex:'searchString',
$options:“我”
}
}, {
“创始人。名字”:{
$regex:'searchString',
$options:“我”
}
}, {
“创始人.赞助人”:{
$regex:'searchString',
$options:“我”
}
}]
}]
}
}, {
$group:{
“_id”:{
“\u id”:“$\u id”,
“组织”:“$organization”,
},
“创始人”:{
“$push”:“$founders”
},
“经理”:{
“$push”:“$managers”
}
}
}, {
$项目:{
“_id”:0,
“创始人”:1,
“经理”1
}
}])
如果要存储在founders&Manager子文档中的数据不大,$regex查询不会导致任何性能瓶颈。谢谢您的回答。你们在结构上基本上是对的,但我的搜索不是在组织名称上,而是在全名组合上。数据集相当庞大,500GB:6000亿个组织(每个组织有1到10000名创始人)。现在我在想-最快的方法是将全名合并到一个字段中。这样它会很快工作。好吧,那么你想要的是一次搜索6000万个组织的创始人和经理。你把你的数据库切分了吗?
{
"_id": ObjectId(''),
"organization": "x",
founders: [
{
lastname: 'a'
firstname: 'a',
patronym: 'a'
},
{
lastname: 'b'
firstname: 'b',
patronym: 'b'
}
],
managers: [
{
{
lastname: 'c'
firstname: 'c',
patronym: 'c'
},
{
lastname: 'd'
firstname: 'd',
patronym: 'd'
}
}
]
}
db.collection.aggregate([{
$match: {
'organization': '<name>'
}
}, {
$unwind: '$managers'
}, {
$unwind: '$founders'
}, {
$match: {
$or: [{
$or: [{
"managers.lastname": {
$regex: 'searchString',
$options: 'i'
}
}, {
"managers.firstname": {
$regex: 'searchString',
$options: 'i'
}
}, {
"managers.patronym": {
$regex: 'searchString',
$options: 'i'
}
}]
}, {
$or: [{
"founders.lastname": {
$regex: 'searchString',
$options: 'i'
}
}, {
"founders.firstname": {
$regex: 'searchString',
$options: 'i'
}
}, {
"founders.patronym": {
$regex: 'searchString',
$options: 'i'
}
}]
}]
}
}, {
$group: {
"_id": {
"_id": "$_id",
"organization": "$organization",
},
"founders": {
"$push": '$founders'
},
"managers": {
"$push": '$managers'
}
}
}, {
$project: {
"_id": 0,
"founders": 1,
"managers" 1
}
}])