MongoDB does not allow duplicating arrays across documents - arrays

So the problem is when I have an array in a document with no values ( is empty []) and when I add another document with an array which does not contain any elements - I face this error message:
Failed to insert document.
Error:
Error when saving document: E11000 duplicate key error collection:
package.package index: collection_name dup key: { : undefined }
How do I allow duplicating values in different arrays across documents?

So the problem was that the array was indexed before and the setting stayed, even though it was recently removed. Simple command db.collection.getIndexes() displayed the index and db.collection.dropIndex("idxName") removed it. Currently the error does not get displayed anymore and I can now add duplicating values across documents.

Related

Catch errors with default for empty indexes

I try to do:
db.table(table)
.max({index: 'number'})('number')
.default(0)
and receive error:
(node:45) UnhandledPromiseRejectionWarning: ReqlQueryLogicError: `max` found no entries in the specified index in:
r.db("db").table("table").max({"index": "number"})("number").default(0)
Is there a way to do it properly?
Your table is empty, or doesn't contain elements with the indexed field "number".
You can try the same query without using the number field as index.
r.db("DB").table("table")
.max('number')('number')
.default(0)
Or fill your table with elements. In this case using the field "number" as index brings you performance advantage.

Mongodb: how to auto-increment a subdocument field?

The following document records a conversation between Milhouse and Bart. I would like to insert a new message with the right num (the next in the example would be 3) in a unique operation. Is that possible ?
{ user_a:"Bart",
user_b:"Milhouse",
conversation:{
last_msg:2,
messages:[
{ from:"Bart",
msg:"Hello"
num:1
},
{ from:"Milhouse",
msg:"Wanna go out ?"
num:2
}
]
}
}
In MongoDB, arrays keep their order, so by adding a num attribute, you're only creating more data for something that you could accomplish without the additional field. Just use the position in the array to accomplish the same thing. Grabbing the X message in an array will provide faster searches than searching for { num: X }.
To keep the order, I don't think there's an easy way to add the num category besides does a find() on conversation.last_msg before you insert the new subdocument and increment last_msg.
Depending on what you need to keep the ordering for, you might consider including a time stamp in your subdocument, which is commonly kept in conversation records anyway and may provide other useful information.
Also, I haven't used it, but there's a Mongoose plugin that may or may not be able to do what you want: https://npmjs.org/package/mongoose-auto-increment
You can't create an auto increment field but you can use functions to generate and administrate sequence :
http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/ 
I would recommend using a timestamp rather than a numerical value. By using a timestamp, you can keep the ordering of the subdocument and make other use of it.

CakePHP 1.3 with muti-type tree

I am using CakePHP 1.3's TreeBehavior. In one DB table I get all the models records. Every record has a type field where the model name is stored. Till now everything is working as a charm. But I get some errors in specific actions. First of all if i do $this->Article->verify() I get errors for almost every record:
Array
(
[0] => Array
(
[0] => index
[1] => 1
[2] => missing
)
[1] => Array
(
[0] => index
[1] => 2
[2] => missing
)
[2] => Array
(
[0] => index
[1] => 3
[2] => missing
)
....
I don't find any difference between the records that has error and those that does not have
I tried Recover but still the same. Why am I getting these errors and what do they mean? I have checked the tree data and every field (parent_id, lft, rght) is correct.
One other issue:
I wold like to move the records up and down in the tree. If I set scope to the record type I move them but all the children records from other types does not move.
My tree is something like this:
Category
Category
Category
Attachment
Category
Attachment
Article
Attachment
Attachment
Article
Attachment
Attachment
Category
Category
If i dont set the scope moving a record sometimes does not see the end of the tree and start moving between other record types. How do I set the scope to avoid this?
EDIT: I have track down the possible problem and probably everything comes from using both Tree and Translate (which i did not mention) behaviours both in multiple Models using one table. So what happen:
When saving Data for each model it also saves a record in the i18n table with the translation. And when checking with verify or recovering the table The Tree behavior only "sees" the posts in the current Model, also giving the "missing index" because not seeing the record from the other models.
Is there any way to fix this, to get it working or to look for other option?
Is there any option to use multiple trees inside one database. So the rght,lft values will be dublicated for every model but there will be no conflict because they will not "know" for each other. Just to use one table and not 10+ with same structure
If your tree metadata is correct then the following should fix any problems which aren't in your own code:
$this->Article->recover($mode = 'tree');
See http://book.cakephp.org/1.3/view/1356/Data-Integrity for more information.

MongoDB - Exclude an inner array but include it's count

I have a table called devicesegments, each row of which contains a large array called devices. Owing to the size of the device array, I've been asked not to include it in my query for a page that lists all devicesegments, but only include their count. Is this possible?
What I was doing before :
A simple db.devicesegments.find()
What I'm doing now :
db.devicesegments.find({}, { devices : 0 })
What I want to achieve :
db.devicesegments.find({}, { devices : 0, devices.length : 1 })
Something like a COUNT(devices) AS device_count!
Ashkay, there's no way to do this with Mongo currently. As #rompetroll says, your application should keep a "count" field on each document, and carefully $inc it whenever you change the number of entries in the array. Then when you query for the document, exclude the array like:
db.collection.find({}, {devices:0})
If you're willing to run MongoDB 2.1, which is a development release, the aggregation framework provides a means to calculate the array size within a query:
http://www.mongodb.org/display/DOCS/Aggregation+Framework
Since there is no way to currently do this, without including a new device_count in my table, the temporary fix that I applied was to fetch all the data from the database, along with the devices array, and for each row, add a field for devices.length and then remove the devices array before sending the data across.

How to ignore errors in datastore.Query.GetAll()?

I just started developing a GAE app with the Go runtime, so far it's been a pleasure. However, I have encountered the following setback:
I am taking advantage of the flexibility that the datastore provides by having several different structs with different properties being saved with the same entity name ("Item"). The Go language datastore reference states that "the actual types passed do not have to match between Get and Put calls or even across different App Engine requests", since entities are actually just a series of properties, and can therefore be stored in an appropriate container type that can support them.
I need to query all of the entities stored under the entity name "Item" and encode them as JSON all at once. Using that entity property flexibility to my advantage, it is possible to store queried entities into an arbitrary datastore.PropertyList, however, the Get and GetAll functions return ErrFieldMismatch as an error when a property of the queried entities cannot be properly represented (that is to say, incompatible types, or simply a missing value). All of these structs I'm saving are user generated and most values are optional, therefore saving empty values into the datastore. There are no problems while saving these structs with empty values (datastore flexibility again), but there are when retrieving them.
It is also stated in the datastore Go documentation, that it is up to the caller of the Get methods to decide if the errors returned due to empty values are ignorable, recoverable, or fatal. I would like to know how to properly do this, since just ignoring the errors won't suffice, as the destination structs (datastore.PropertyList) of my queries are not filled at all when a query results in this error.
Thank you in advance, and sorry for the lengthy question.
Update: Here is some code
query := datastore.NewQuery("Item") // here I use some Filter calls, as well as a Limit call and an Order call
items := make([]datastore.PropertyList, 0)
_, err := query.GetAll(context, &items) // context has been obviously defined before
if err != nil {
// something to handle the error, which in my case, it's printing it and setting the server status as 500
}
Update 2: Here is some output
If I use make([]datastore.PropertyList, 0), I get this:
datastore: invalid entity type
And if I use make(datastore.PropertyList, 0), I get this:
datastore: cannot load field "Foo" into a "datastore.Property": no such struct field
And in both cases (the first one I assume can be discarded) in items I get this:
[]
According to the following post the go datastore module doesn't support PropertyList yet.
Use a pointer to a slice of datastore.Map instead.

Resources