I'm working on building a database from a set of CSV files and am running into issues pushing elements to a deeply nested array. I've seen examples for 2D arrays and the use of positional operators but I can't quite figure out how to use them for my situation.
What I am trying to do read the CSV file which has columns for the answer_id and the url string for the photo. I want to push the url string to the photos array for the corresponding answer_id. When I try to use the code below, I get a long error message which starts with:
MongoBulkWriteError: Cannot create field 'answers' in element
{
results: [
{
question_id: "1",
_id: ObjectId('6332e0b015c1d1f4eccebf4e'),
answers: [
{
answer_id: "5",
//....
}
],
}
]
}
I formatted the above message to make things easier to read. It may be worth noting the first row of my CSV file has '5' in the answer_id column which makes me think things are failing at the first try to update my document.
Here is an example of my code:
const ExampleModel = new Schema({
example_id: String,
results: [
{
question_id: String,
answers: [
{
answer_id: String,
photos: [
{ url: String },
]
}
]
}
]
});
// Example Operation
// row.answer_id comes from CSV file
updateOne: {
'filter': {
'results.answers.answer_id': row.answer_id,
},
'update': {
'$push': {
'results.answers.$.photos' : { 'url': 'test'}
}
}
}
I guess my question is can I update an array this deeply nested using Mongoose?
Related
I'm trying to execute the following query with Firestore REST API, and I find the documentation to be very limited on more complex queries. Basically I want to use WHERE IN query.
const allowedIds = ['xxxx', 'zzzz', 'yyyy'];
let myQuery = firebase.firestore().collection('myCollection').where(firebase.firestore.FieldPath.documentId(), 'in', allowedIds);
This one works perfectly, but now I want to convert it around. Here is what I've tried so far:
const allowedIds = ['xxxx', 'zzzz', 'yyyy'];
'structuredQuery': {
'from': [{
'collectionId': 'myCollection',
}],
'where': {
'fieldFilter': {
'field': {
'fieldPath': firebase.firestore.FieldPath.documentId(),
},
'op': 'IN',
'arrayValue': {
'values': [
{
'stringValue': 'xxxx',
},
{
'stringValue': 'zzzz',
},
],
},
},
},
},
It seems that the problem is in using firebase.firestore.FieldPath.documentId() to reference a document ID, but is there another way to achieve that?
The error message I currently get:
"Invalid value at 'structured_query.where.field_filter.field' (field_path), Starting an object on a scalar field
Invalid JSON payload received. Unknown name "arrayValue" at 'structured_query.where.field_filter': Cannot find field."
My data structure: I have vehicles and users collections. Users have a field called vehicles which is an array of strings(vehicles collection document id-s). So I would like to query vehicles collection WHERE IN the user.vehicles
Try replacing firebase.firestore.FieldPath.documentId() by "__name__".
My mongoose Scheme is as follows
Project: {
name: String,
stat: Number,
users: [
{user_id: String}
]
}
So each project contains multiple users. I am provided with two user ids and I need to find documents which contain both of those ids. Tried using elemmatch but can't figure out correct syntax. Please suggest ways to find documents like these.
This is the code I tried
Project.find({
users: {
$elemMatch: { id: req.query.id1 },
$elemMatch: { id: req.query.id2 }
}
})
but this returns all project which contains any one of the ids, not both.
So my original code was OK, it was not running due to some minor errors in other areas.
Project.find({
users: {
$elemMatch: { id: req.query.id1 },
$elemMatch: { id: req.query.id2 }
}
})
This is the code. I'll keep it here in case someone faces the same problem
I'm having some trouble searching an array I have in my model which currently contains dummy posts.
My posts array looks like this
posts: [
{
image: <filename>,
comments: [],
joined: <number>,
}
]
The posts array atm holds about 10 objects. I need a way to query this array and return a single object. I already tried the answers given on other similar questions, but they all return the whole user which is not what I want.
I tried this:
model
.find(
{ $match : { "posts.image": req.params.image } },
{ $unwind : "$posts" },
{ $match : { "posts.image": req.params.image } }
)
This also returns the whole object including the password, username, etc. I also tried $elemMatch, and no luck.
I'm only expecting it to return one object (not multiple objects) since ill be querying the array with req.params.
Unsure
Not entirely certain if this is what you are asking for, but a way to get a single property value of an array would be done this way
If I am misunderstood please clarify what you are after and I will amend my answer.
var posts = [{
image: "x.jpg",
comments: [],
joined: 12
},
{
image: "x1.jpg",
comments: [],
joined: 121
},
{
image: "ax.jpg",
comments: [],
joined: 2
}
];
for (a = 0; a < posts.length; a++){
console.log(posts[a].image);
}
Basically I got my app up an running but I'm stuck with a problem: if I pass an object that contains an empty array to be saved, the array is not saved into the db. I'm not sure this is a problem in js or the mongo driver, but in order to save the empty array I need to pass the array like so: products: [''].
This is the structure of my mongo document:
_id: ObjectId(...),
name: 'String',
subcategories: [
{
subcategory: 'string',
products: [
{
name: 'string'
price: integer
}
]
}
]
So in my front-end I'm grabbing the whole document through an ajax call pushing a new object into the subcategories array. The new object looks like this:
{subcategory:'string', products:['']}
And this works okay until I need to insert a new object inside the array: Because I've grabbed the whole object, pushed the new object to the array, the previous one looks like this:
{subcategory: 'string'}
Having lost the mention to products:[] array in the process.
How can I get around this? I need to be able to have empty arrays in my object.
EDIT
What I did on front end: Got the whole object with $.get which returned:
var obj =
_id: ObjectId(...),
name: 'String',
subcategories: [
{
subcategory: 'Subcategory1',
products: [
{
name: 'string'
price: integer
}
]
}
];
Then on the front end I've pushed the new object category inside the subcategories array:
data.subcategories.push({subcategory: 'Subcategory2', products: ['']})
Where subcat was a string with the category name. On my db I could see that I've successfully added the object:
var obj =
_id: ObjectId(...),
name: 'String',
subcategories: [
{
subcategory: 'Subcategory1',
products: [
{
name: 'string'
price: integer
}
]
},
{
subcategory: 'Subcategory2'
products: []
}
];
The problem was when I wanted to add another subcategory, the previous one return empty:
var obj =
_id: ObjectId(...),
name: 'String',
subcategories: [
{
subcategory: 'Subcategory1',
products: [
{
name: 'string'
price: integer
}
]
},
{
subcategory: 'Subcategory2'
},
{
subcategory: 'Subcategory3'
products: []
},
];
Because at some point the empty array was removed from the object. Like I said, I did fix this in the front end, so the error jade was throwing has been addressed, but I still find odd that the products: [] was being removed from the document.
I'm new to MongoDb and node, not to mention that I'm also new with JS, so it might well be a feature that I'm unaware of.
When passing empty arrays to Mongo they are interpreted as empty documents, {}. Zend Json encoder will interpret them as empty arrays []. I understand that it's not possible to tell which one is correct.
Incase of empty arrays try posting as
Array[null];
instead of Array[];
This will be working fine
When passing empty arrays to Mongo they are interpreted as empty documents, {}. Zend Json encoder will interpret them as empty arrays []. I understand that it's not possible to tell which one is correct.
In my view it's more logical that the actual php array (when empty) is interpreted as an array in MongoDB. Although that will require something else to identify empty documents it's still more logical than the current behaviour.
A possible solution would be to introduce a new object, MongoEmptyObject (or using the stdObj) whenever one want to introduce an empty object.
Meanwhile, a workaround is to detect empty arrays in php, and inject a null value $arr[0] = null;
Then the object will be interpreted as an empty array in mongo.
The workaround works both in PHP and in the mongo console. Question: does json allow for arrays with null values? If so, then the workaround is a sign of another bug.
PHP:
if (is_array($value) && empty($value))
{ $value[0] = null; }
Mongo Console:
var b =
{hej:"da", arr: [null]}
db.test.save(b);
db.test.find();
{"_id" : "4a4b23adde08d50628564b12" , "hej" : "da" , "arr" : []}
I've looked around quite a bit concerning this error, it seems that Mongo won't accept a . or a $ in an update, yet I still get this error
{ [MongoError: not okForStorage]
name: 'MongoError',
err: 'not okForStorage',
code: 12527,
n: 0,
connectionId: 18,
ok: 1 }
This is the object I'm updating:
{
status: "open",
type: "item",
parentId: "4fa13ba2d327ca052d000003",
_id: "4fa13bd6d327ca052d000012",
properties: {
titleInfo: [
{ title: "some item" }
]
}
}
And I'm updating it to:
{
fedoraId: 'aFedoraLib:438',
status: "closed",
type: "item",
parentId: "4fa13ba2d327ca052d000003",
_id: "4fa13bd6d327ca052d000012",
properties: {
titleInfo: [
{ title: "some item" }
]
}
}
Another possible cause I just ran into: storing an object which has periods in the string keys.
So for people getting the same error:
It's due to the fact that I was including the _id, which Mongo doesn't like apparently
I ran into this error when trying to save a JSON structure with this key-value pair (coming straight out of an AngularJS app):
"$$hashKey":"021"
Removing just that key fixed the problem. For others using Angular, it looks like calling Angular's built-in angular.toJson client-side eliminates the $$hashkey keys. From their forums:
$scope.ngObjFixHack = function(ngObj) {
var output;
output = angular.toJson(ngObj);
output = angular.fromJson(output);
return output;
}