On my car mongodb collection I have user_id and default_car fields. One user can have only one default car but can have multiple non-default cars. For instance this value should be valid :
[{user_id:1,default_car:true},{user_id:2,defaut_tool:true},{user_id:2,defaut_tool:false},{user_id:2,defaut_tool:false}]
user with id 1 has only one car but user with id 2 has 3 cars and one of them is the default one. This example should be invalid :
[{user_id:1,default_car:true},{user_id:2,defaut_tool:true},{user_id:2,defaut_tool:true},{user_id:2,defaut_tool:false}]
What kind of constraint Do I need to define ? I use mongoose on nodejs.
If you are looking to satisfy a uniqueness constraint within MongoDB, then you will want to look into unique indexes.
In your particular situation, it sounds like the uniqueness constraint should be enforced is that each specific user_id cannot have more than one default_car. Therefore you your index should also be a partial index. Specifically the index should probably resemble the following:
db.<collectionName>.createIndex({_user_id:1},{unique:true, partialFilterExpression:{default_car:true}})
Related
I am completely new using elastic search with current project(elastic-builder is used) and documentation of elastic-builder is bit confusing.
I need to retrieve all unique values of one specific field, say creator of tasks stored on server, how should I compose the query to achieve this?
You can use the terms aggregation to get all the unique values sorted by count from a field. If you use the default mapping for your index, your creator field should have a subfield creator.keyword that you can use for the terms aggregation.
I have a collection of employees that has data sent to it. Right now there is 4 employees but eventually there will be many more.
I want to add a grouping feature so that the user can sort the employees by their group. I am trying to find the best way to assign these employees groups and I found the reference field type in cloud firestore and thought I could use it to solve my problem. But I am stuck and not sure the most efficeient way to use it to link employees to a group.
This is my database. Right now I have the employees doc (ex. 2569) and inside that is a sub-collection with 2 documents in itself.
So end goal is to assign employees groups and then be able to sort and display them separately. Right now I have the group name assigned in articles/group -> groupName: "example".
(display them hopefully with ".Where( "groupName" "==" "example" ) somehow in code without hard-coding the group name. The group name will be created by the user so it could be anything)
Is what I am doing a good start? I know this question is a little odd but I am stuck and could really use some pointers on where to head next.
A collection group query would allow you to query all articles regardless of which employee contained them:
db.collectionGroup('articles')
.where('groupName', '==', 'X')
.get()
This would match documents in any collection (i.e. employees) where the last part of the collection path is articles. If you would like to find the employees who belong to a certain groupName, you may want to find the parent by retrieving the collection this DocumentReference belongs to.
Once you have the parent of the CollectionReference, you will get a reference to the containing DocumentReference of your subcollection.
Is there any methods or packages, that can help me add auto increments to existing collection? Internet full of information, about how to add AI before you create collection, but I did not find information on how to add AI when collection already exist...
MongoDB does not have an inbuilt auto-increment functionality.
Create a new collection to keep track of the last sequence value used for insertion:
db.createCollection("counter")
It will hold only one record as:
db.counter.insert({_id:"mySequence",seq_val:0})
Create a JavaScript function as:
function getNextSequenceVal(seq_id){
// find record with id seq_id and update the seq_val by +1
var sequenceDoc = db.counter.findAndModify({
query:{_id: seq_id},
update: {$inc:{seq_val:1}},
new:true
});
return sequenceDoc.seq_val;
}
To update all the already existing values in your existing collection, this should work (For the empty {}, you can place your conditions if you want to update some documents only):
db.myCollection.update({},
{$set:{'_id':getNextSequenceVal("mySequence")}},{multi:true})
Now you can insert new records into your existing collection as:
db.myCollection.insert({
"_id":getNextSequenceVal("mySequence"),
"name":"ABC"
})
MongoDB reserves the _id field in the top level of all documents as a primary key. _id must be unique, and always has an index with a unique constraint. It is an auto-incrementing field. However, it is possible to define your own auto-incrementing field following the tutorial in the MongoDB documentation.
Tutorial link: https://docs.mongodb.com/v3.0/tutorial/create-an-auto-incrementing-field/
I have two classes - _User and Car. A _User will have a low/limited number of Cars that they own. Each Car has only ONE owner and thus an "owner" column that is a to the _User. When I got to the user's page, I want to see their _User info and all of their Cars. I would like to make one call, in Cloud Code if necessary.
Here is where I get confused. There are 3 ways I could do this -
In _User have a relationship column called "cars" that points to each individual Car. If so, how come I can't use the "include(cars)" function on a relation to include the Cars' data in my query?!!
_User.cars = relationship, Car.owner = _User(pointer)
Query the _User, and then query all Cars with (owner == _User.objectId) separately. This is two queries though.
_User.cars = null, Car.owner = _User(pointer)
In _User have a array of pointers column called "cars". Manually inject pointers to cars upon car creation. When querying the user I would use "include(cars)".
_User.cars = [Car(pointer)], Car.owner = _User(pointer)
What is your recommended way to do this and why? Which one is the fastest? The documentation just leaves me further confused.
I recommend you the 3rd option, and yes, you can ask to include an array. You even don't need to "manually inject" the pointers, you just need to add the objects into the array and they'll automatically be converted into pointers.
You've got the right ideas. Just to clarify them a bit:
A relation. User can have a relation column called cars. To get from user to car, there's a user query and then second query like user.relation("cars").query, on which you would .find().
What you might call a belongs_to pointer in Car. To get from user to car you'd have a query to get your user and you create a carQuery like carQuery.equalTo("user", user)
An array of pointers. For small-sized collections, this is superior to the relation, because you can aggressively load cars when querying user by saying include("cars") on a user query. Not sure if there's a second query under the covers - probably not if parse (mongo) is storing these as embedded.
But I wouldn't get too tied up over one or two queries. Using the promise forms of find() will keep your code nice and tidy. There probably is a small speed advantage to the array technique, which is good while the collection size is small (<100 is my rule of thumb).
It's easy to google (or I'll add here if you have a specific question) code examples for maintaining the relations and for getting from user->car or from car->user for each approach.
I have the following generic schema to represent different types of information.
var Record = new Schema (
{
type: {type: String}, // any string (foo, bar, foobar)
value: {type: String}, // any string value
o_id: {type:String}
}
);
Some of the records based on this schema have:
type="car"
value="ferrari" or
value="ford"
Some records have type "topspeed" with value "210" but they always share o_id (e.g. related "ferrari has this topspeed"). So if "ferrari has top speed 300", then both records have same o_id.
How can I make query to find "ferrari with topspeed 300" when I don't know o_id?
The only solution I found out is to select cars "ferrari" first and then with knowledge of all o_id for all "ferrari" use it to find topspeed.
In pseudocode:
Record.find({type:"car", value:"ferrari"}, function(err, docs)
{
var condition = [];// create array of all found o_id;
Record.find({type:"topspeed", value:"300"}...
}
I know that some merging or joining might not be possible, but what about some chaining these conditions to avoid recursion?
EDIT:
Better example:
Lets imagine I have a HTML document that contains DIV elements with certain id (o_id).
Now each div element can contain different type of microdata items (Car, Animal...).
Each microdata item has different properties ("topspeed", "numberOfLegs"...) based on the type (Car has a topspeed, animal numberOfLegs)
Each property has some value (310 kph, 4 legs)
Now I'm saving these microdata items to the database but in a general way, agnostic of the type and values they contain since the user can define custom schemas from Car, to Animal, to pretty much anything). For that I defined the Record schema: type consists of "itemtype_propertyname" and value is value of the property.
I would eventually like to query "Give me o_id(s) of all DIV elements that contain item Ferrari and item Dog" at the same time.
The reason for this general approach is to allow anyone the ability to define custom schema and corresponding parser that stores the values.
But I will have only one search engine to find all different schemas and value combinations that will treat all possible schemas as a single definition.
I think it'd be far better to combine all records that share an o_id into a single record. E.g.:
{
_id: ObjectId(...),
car: "ferarri",
topspeed: 300
}
Then you won't have this problem, and your schema will be more efficient both in speed and storage size. This is how MongoDB is intended to be used -- heterogenous data can be stored in a single collection, because MongoDB is schemaless. If you continue with your current design, then no, there's no way to avoid multiple round-trips to the database.