【问题标题】:mongodb: Search a collection for all IDs in an array of objectsmongodb:在集合中搜索对象数组中的所有 ID
【发布时间】:2015-07-24 15:36:22
【问题描述】:

我有一个只有 ObjectID 的对象数组,我想在一个集合中搜索所有具有这些 ID 的文档。

var array = [{ _id: 5551e59be360594cd3319644 },
             { _id: 5551e59be360594cd3319631 },
             { _id: 5551e59be360594cd33195d2 },
             { _id: 5551e59be360594cd3319627 }];

这是我目前正在做的事情:

for (var i = 0; i < array.length; i++) {
  db.collection('test').findOne({_id:array[i]._id}, function(err, matched) {
    console.log(matched);
});

我尝试使用 $inoperator 但没有成功,因为它不是一个 ID 数组,而是一个包含这些 ID 的对象数组。

是否有另一种方法可以仅使用一个数据库查询来执行此操作,因为我认为在 for 循环中执行如此多的数据库查询不是一个好主意。

编辑 我现在用 map 方法尝试了它(就像@chrisdam 解释的那样),所以我有一个 ID 数组,但是当我将它传递给 find 方法时,我得到了这个结果:

EDIT2 没关系我的第一次编辑。 find() 只返回一个游标,而不是文档本身。所以我使用了toArray()。感谢您的帮助@chrisdam!

{ db:
  { domain: null,
    _events: {},
    _maxListeners: undefined,
    databaseName: 'test',
    serverConfig: { 
      domain: null,
      _events: {},
      _maxListeners: undefined,
      auth: [Getter],
      _callBackStore: [Object],
      _commandsStore: [Object],
      _dbStore: [Object],
      host: 'localhost',
      port: 27017,
      options: [Object],
      internalMaster: true,
      connected: true,
      poolSize: 5,
      disableDriverBSONSizeCheck: false,
      _used: true,
      replicasetInstance: null,
      emitOpen: false,
      ssl: false,
      sslValidate: false,
      sslCA: null,
      sslCert: undefined,
      sslKey: undefined,
      sslPass: undefined,
      serverCapabilities: [Object],
      name: 'localhost:27017',
      socketOptions: [Object],
      logger: [Object],
      eventHandlers: [Object],
      _serverState: 'connected',
      _state: [Object],
      recordQueryStats: false,
      socketTimeoutMS: [Getter/Setter],
      _readPreference: [Object],
      db: [Circular],
      dbInstances: [Object],
      connectionPool: [Object],
      isMasterDoc: [Object] },
    options: { 
      read_preference_tags: null,
      read_preference: 'primary',
      url: 'mongodb://localhost:27017/test',
      native_parser: true,
      readPreference: [Object],
      safe: false,
      w: 1 },
    _applicationClosed: false,
    slaveOk: false,
    bufferMaxEntries: -1,
    native_parser: true,
    bsonLib: { 
      BSON: [Object],
      Long: [Object],
      ObjectID: [Object],
      DBRef: [Object],
      Code: [Object],
      Timestamp: [Object],
      Binary: [Object],
      Double: [Object],
      MaxKey: [Object],
      MinKey: [Object],
      Symbol: [Object] },
    bson: { promoteLongs: true },
    bson_deserializer: { 
      Code: [Object],
      Symbol: [Object],
      BSON: [Object],
      DBRef: [Object],
      Binary: [Object],
      ObjectID: [Object],
      Long: [Object],
      Timestamp: [Object],
      Double: [Object],
      MinKey: [Object],
      MaxKey: [Object],
      promoteLongs: true },
    bson_serializer: { 
      Code: [Object],
      Symbol: [Object],
      BSON: [Object],
      DBRef: [Object],
      Binary: [Object],
      ObjectID: [Object],
      Long: [Object],
      Timestamp: [Object],
      Double: [Object],
      MinKey: [Object],
      MaxKey: [Object],
      promoteLongs: true },
    _state: 'connected',
    pkFactory: { 
      [Function: ObjectID]
      index: 13651524,
      createPk: [Function: createPk],
      createFromTime: [Function: createFromTime],
      createFromHexString: [Function: createFromHexString],
      isValid: [Function: isValid],
      ObjectID: [Circular],
      ObjectId: [Circular] },
    forceServerObjectId: false,
    safe: false,
    notReplied: {},
    isInitializing: true,
    openCalled: true,
    commands: [],
    logger: { error: [Function], log: [Function], debug: [Function] },
    tag: 1431517732801,
    eventHandlers: { 
      error: [],
      parseError: [],
      poolReady: [],
      message: [],
      close: [] },
    serializeFunctions: false,
    raw: false,
    recordQueryStats: false,
    retryMiliSeconds: 1000,
    numberOfRetries: 60,
    readPreference: { _type: 'ReadPreference', mode: 'primary', tags: undefined } },
  collection: { 
    db: { 
      domain: null,
      _events: {},
      _maxListeners: undefined,
      databaseName: 'test',
      serverConfig: [Object],
      options: [Object],
      _applicationClosed: false,
      slaveOk: false,
      bufferMaxEntries: -1,
      native_parser: true,
      bsonLib: [Object],
      bson: [Object],
      bson_deserializer: [Object],
      bson_serializer: [Object],
      _state: 'connected',
      pkFactory: [Object],
      forceServerObjectId: false,
      safe: false,
      notReplied: {},
      isInitializing: true,
      openCalled: true,
      commands: [],
      logger: [Object],
      tag: 1431517732801,
      eventHandlers: [Object],
      serializeFunctions: false,
      raw: false,
      recordQueryStats: false,
      retryMiliSeconds: 1000,
      numberOfRetries: 60,
      readPreference: [Object] },
    collectionName: 'sick',
    internalHint: null,
    opts: {},
    slaveOk: false,
    serializeFunctions: false,
    raw: false,
    readPreference: { _type: 'ReadPreference', mode: 'primary', tags: undefined },
    pkFactory: { 
      [Function: ObjectID]
      index: 13651524,
      createPk: [Function: createPk],
      createFromTime: [Function: createFromTime],
      createFromHexString: [Function: createFromHexString],
      isValid: [Function: isValid],
      ObjectID: [Circular],
      ObjectId: [Circular] },
    serverCapabilities: undefined },
  selector: { _id: { '$in': [Object] } },
  fields: undefined,
  skipValue: 0,
  limitValue: 0,
  sortValue: undefined,
  hint: null,
  explainValue: undefined,
  snapshot: undefined,
  timeout: true,
  tailable: undefined,
  awaitdata: undefined,
  oplogReplay: undefined,
  numberOfRetries: 5,
  currentNumberOfRetries: 5,
  batchSizeValue: 0,
  raw: false,
  readPreference: { _type: 'ReadPreference', mode: 'primary', tags: undefined },
  returnKey: undefined,
  maxScan: undefined,
  min: undefined,
  max: undefined,
  showDiskLoc: undefined,
  comment: undefined,
  tailableRetryInterval: 100,
  exhaust: false,
  partial: false,
  slaveOk: false,
  maxTimeMSValue: undefined,
  connection: undefined,
  transforms: undefined,
  totalNumberOfRecords: 0,
  items: [],
  cursorId: { _bsontype: 'Long', low_: 0, high_: 0 },
  dbName: undefined,
  state: 0,
  queryRun: false,
  getMoreTimer: false,
  collectionName: 'test.sick' }

【问题讨论】:

  • 为什么不遍历列表并创建一个仅包含 ID 的新列表,然后将其与 $in 运算符一起使用。
  • @Sir_FZ 我们基本上是用地图功能做到的,不是吗?

标签: arrays mongodb search


【解决方案1】:

您可以尝试 JavaScript 的原生 map 方法来生成一个 ObjectIds 数组,然后您可以将其与 $in 运算符一起使用,如下所示:

var array = [{ _id: "5551e59be360594cd3319644" },
             { _id: "5551e59be360594cd3319631" },
             { _id: "5551e59be360594cd33195d2" },
             { _id: "5551e59be360594cd3319627" }],    
    ids = array.map(function (obj){ return ObjectId(obj._id)});

db.collection.find({ "_id": { "$in": ids }});

或者只使用 $or 运算符作为:

var array = [{ _id: "5551e59be360594cd3319644" },
             { _id: "5551e59be360594cd3319631" },
             { _id: "5551e59be360594cd33195d2" },
             { _id: "5551e59be360594cd3319627" }],    
    ids = array.map(function (obj){ return { _id: ObjectId(obj._id) } });   

db.collection.find({ "$or": ids });

【讨论】:

  • 有没有办法获取 id,然后在单个查询中获取这些 id 的对应对象(可能有某种形式的聚合)?谢谢
猜你喜欢
  • 2012-07-08
  • 2012-01-06
  • 2020-04-19
  • 1970-01-01
  • 2022-01-04
  • 2013-07-17
  • 2018-08-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多