在MongoDB中搜索范围,想要子元素,而不是整个文档

时间:2017-02-17 06:14:41

标签: mongodb mongodb-query

我的MongoDB文档结构相当复杂:

顶级组织(一个元素)

数十个属性,其中有趣的是创始人经理

创始人 - 是一个创始人列表,每个都有姓氏,名字,姓名(和其他属性)

经理相同 - 包含姓氏,名字,姓名(和其他属性)的元素列表

我想通过lastname + firstname + patronym combo在一个查询中搜索。 查询应该支持多个姓氏,名字,副词(在$ in的帮助下)(这是针对一个人的不同名称,即jon,john,johny)

我当前的代码在ORGANIZATION中返回名字为+ firstname + patronym combo的组织,但我需要在PERSON中使用lastname + firstname + patronym combo。可能吗?即使是正确的方向,也不是代码,将不胜感激。据我了解,$ elemMatch不会帮助我或查询会非常麻烦吗?也许存在一些更清洁的选择?

我已经尝试过更改

List<BasicDBObject> args 

代表

BasicDBObject name

并使用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>());

实际上,在最终的argsListUL中还有更多的DBObject,但为了简单起见,我删除了该代码。

更新 尝试使用$ elemMatch在shell中构建最简单的查询。奇怪,但它不起作用:

db.collection.find( { "founders.typeperson.person": { $elemMatch: { "lastname": "bla" , "firstname": "bla","patronym" : "bla"  } } } ).pretty()

获得0结果。虽然DB中存在lastname + firstname + patronym的组合。

另一个注意事项:数据库的大小是500GB,所以我认为投影中的$ elemMatch会太慢。

1 个答案:

答案 0 :(得分:0)

您可以尝试共享数据库方案。您的数据库方案不清楚。

虽然从我的理解,你有一个数据结构如下。虽然结构或要求有所不同,但我会更新答案。

{
  "_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
  }
}])

如果数据存储在创始人和管理器子文档不大,$ regex查询不会导致任何性能瓶颈。