简体   繁体   中英

Mongoose, find by element in array

I'm trying to find all documents with a certain value in an array field using Mongoose and Node.js. I can do this in MongoDB with no trouble, but I'm having difficulty in Mongoose. I used Find document with array that contains a specific value as my guide for how to do this, but I'm not getting the results I expect. My model:

const mongoose = require("mongoose");

const Schema = mongoose.Schema;
const ApptSchema = new Schema({
  store: { type: String, required: true },
  dotw: { type: String, required: true },
  month: { type: Number, required: true },
  day: { type: Number, required: true },
  hr: { type: Number, required: true },
  min: { type: Number, required: true },
  customers: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
  full: { type: Boolean, required: true, default: false }
});

const Appt = mongoose.model("Appt", ApptSchema);

module.exports = Appt;

I want to find all documents that contain a certain customer id. In MongoDB shell, this is what I would do:

db.appts.find({customers: "5e7e3bc4ac4f196474d8bf69"})

This works as expected, giving me all documents, (one document in this case), where this id is in the customers array.

{ "_id" : ObjectId("5e7e719c806ef76b35b4fd69"), "customers" : [ "5e7e3bc4ac4f196474d8bf69" ], "full" : false, "store" : "Nashville", "dotw" : "Friday", "month" : 4, "day" : 15, "hr" : 13, "min" : 0 }

In Mongoose, this is what I'm trying:

Appt.find({ customers: "5e7e3bc4ac4f196474d8bf69" }, (err, docs) => {
    if (err) {
      console.log(err);
    } else {
      console.log(docs);
    }
  });

This prints an empty array, even though there is clearly a document where this id is in the customers array. This seems like this should work, but I'm clearly missing some piece of the puzzle. Any insight into what I'm doing wrong would be very much appreciated.

Edit: In case anyone would like to/be willing to take a more in-depth look, a GitHub repo of the app so far can be found here . The query in question is in routes/routes.js at line 111 (as of the time of writing).

Another edit: It appears this has something to do with the Schema type of the field in question. I eliminated the ref attribute of the entries in the customers field, just in case that was causing a problem, but my query still returned an empty array. The next test was to add a new field to my model, myStrings: [String] . I then added a string to the array of one of my Appt documents, "working" , and queried Appt.find({myStrings: "working"}) and this finally returns the Appt document that I updated. This tells me there's something squirrely about working with the mongoose.Schema.Types.ObjectId , but I can't figure out how to resolve it.

FINAL EDIT: After much tribulation, this is solved. The issue was as follows... For testing, I was adding items to my database using MongoDB shell, which does not enforce data types like Mongoose does. I didn't realize that I was simply adding user ids as strings to the customers array. When Mongoose went looking for ObjectIds, of course it didn't find any, and returned an empty array. Adding customers to the customers array with db.appts.updateOne({<whatever information>},{$push:{customers: new ObjectId(<id string>)}}) , Mongoose was able to return the information I was looking for.

I would say your problem is that you are using a String in the filter, where the field is of ObjectId type. Therefore, you need to convert the string to ObjectId first for mongoose to be able to query it correctly.

Appt.find({ customers: mongoose.Types.ObjectId("5e7e3bc4ac4f196474d8bf69") }, (err, docs) => {});

add the _id field:

Appt.find({ customers._id: "5e7e3bc4ac4f196474d8bf69" }, (err, docs) => {
if (err) {
  console.log(err);
} else {
  console.log(docs);
}});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM