Regarding querying in cloud firestore - flutter

I'm doing some research on cloud firestore using flutter. Currently I'm looking into querying in cloud firestore. I got a basic idea of how to query like say in the screenshot of the database given below :
The 2nd (Some Dumb Shit) and 3rd (Some Good Shit) projects belong to the field "Hardware" ..... So if I want to search a project with respect to its field ..... I'll do something like this :
databaseReference.collection("Projects").where("Field",isEqualTo: "Hardware")
But say if I want to search projects based on the name of the members ( Referring to the screenshot above ..... I need to search of a project where a name "Sarvesh Dalvi" is present inside the "Members" field). How am I supposed to write a query in this case.
Note :
Name ("Sarvesh Dalvi") is present inside this heirarchy :
DocumentID(eg : "Some Dumb Shit") / Array("Members") / Map({Name : __ , MemberRef :__});
Thanks in advance for the help.
Update :
I learned how to access an array by doing something like this :
Future<dynamic> getUserProjectFromDatabase(String username)
{
return databaseReference.collection("Projects").where("Members",arrayContains: {"Name" : username}).getDocuments().then((value){
print(value.documents.length);
value.documents.forEach((element) {print(element.data);});
});
}
But this works if the Map only contains :
{"Name" : username};
But in my case my Map is something like this :
{
"Name" : username,
"MemberRef" : /*Reference to a Document*/
};
[Refer to the screenshot posted above]
I only want to query for the Name inside the map and not the MemberRef...... so how can I query something like :
Future<dynamic> getUserProjectFromDatabase(String username)
{
return databaseReference.collection("Projects").where("Members",arrayContains: {"Name" : username,"MemberRef" : /* can be anything */}).getDocuments().then((value){
print(value.documents.length);
value.documents.forEach((element) {print(element.data);});
});
}

There is no way to query for just the member name in your current data structure.
You have two main options:
If you also know the MemberRef for the member, you can query with array-contains: where('Members', arrayContains: {'Name':'New User','MemberRef':'value of memberref'}). This works because array-contains can check if the array contains the complete value that you specify.
If you don't know the MemberRef subbfield, then you'll need to change your data model to allow the query. I typically recommend creating an additional field with just the member names: MemberNames: ["New User", "Sarvesh Dalvi"]. Then you can use the same array-contains operator, but now on this new field with the simple type: where('MemberNames', arrayContains: 'New User').

Related

MongoDB Find and Modify With GraphQL

I am working on GraphQL mutation and need help here. My document looks like
{
"_id" : ObjectId("5bc02db357146d0c385d4988"),
"item_type" : "CategoryMapping",
"id" : null,
"CategoryGroupName" : "Mystries & Thriller",
"CustomCategory" : [
{
"name" : "Private Investigator",
"MappedBisacs" : [
"investigator",
"Privately owned",
"Secret"
]
},
{
"name" : "Crime Investigator",
"MappedBisacs" : [
"crime investigator",
"crime thriller"
]
}
]
}
UI
Allow user to update MappedBisacs through list of checkbox. So user can add/update or delete list of bisacs.
Problem - When client send GraphQL query like following;
mutation {
CategoryMapping_add(input: {CategoryGroupName: "Mystries & Thriller", CustomCategory: [{name: "Crime Investigator", MappedBisacs: ["investigator", "dafdfdaf", "dafsdf"]}]}) {
clientMutationId
}
}
I need to find Specific custom category and update its bisac array.
I am not sure if I got it, but this more a doubt on MongoDb than on GraphQL itself. First you must find the document that you want (I would use the id of the document instead of CategoryGroupName), then you can update this array in several ways. For example, after you found the document, you could simply access the array content and spread into a new one adding this new data from your mutation, and save this object with the update method. (if you simply want to add new data without removing any)
So, it depends on the case.
Check: https://docs.mongodb.com/manual/reference/operator/update-array/
Hope it helps! :)

Query object within object

I'm using passport.js to store my users into my mongodb. A user object looks like this
{
"_id" : ObjectId("54893faf0907a100006341ee"),
"local" : {
"password" : [encrypted password],
"email" : "johnsmith#domain.com"
},
"__v" : 0
}
In a mongodb shell how would I go about listing all the emails? I'm finding it difficult to do this as my data sits two level deep within the object. Cheers!
You can use distinct to get a list of a field's distinct values in the collection, using dot notation to reference the embedded field:
db.users.distinct('local.email')

mongodb query in 2 collections

I have define 2 reconds in 2 collections separately in one mongo db like this
order:
{
"_id" : ObjectId("53142f58c781abdd1d836fcd"),
"number" : "order1",
"user" : ObjectId("53159bd7d941aba0621073e3")
}
user
{
"_id" : ObjectId("53159bd7d941aba0621073e3"),
"name" : "user1",
"gender" : "male"
}
when I use this command in console, it can not execute
db.orders.find({user: db.user['_id']}) or db.orders.find({user: user['_id']}),
is there anything wrong? Thanks!
Another way is to:
> var user = db.users.findOne({name: 'user1'});
> db.orders.find({user: user._id});
This way can be a bit more flexible especially if you want to return orders for multiple users etc.
Taking your comment:
Thanks, but actually, I want to search all the orders of all users, not only one user. So what would I do? Thanks
db.users.find().forEach(function(doc){
printJson(db.orders.find({user: doc._id}));
});
I think you want:
db.order.find({'user':db.users.findOne({'name':'user1'})._id})
All you need to do is to make a query and check the output before inserting it into the query.
i.e. check that:
db.users.findOne({'name':'user1'})._id
has the output:
ObjectId("53159bd7d941aba0621073e3")
If you want to run larger queries, you're going to have to change your structure. Remember that Mongodb doesn't do joins so you'll need to do create a user document that looks like this:
user
{
"name":"user1",
"gender":"male",
"orders":[
{
'number':'order1'
}
]
}
You can then update this using:
db.user.update({'_id':ObjectId('blah')}, {'orders':{$push:{'number':'order2'}})
This will then start you with order tracking.
Mongo will be able to find using the following:
db.user.find({'orders.numbers':'order2'})
returning the full user record
Maybe you can help this solution:
use orders
db.getCollection('order').find({},{'_id':1})
db.getCollection('user').find({},{'_id':1})

How to search by integer type column using morphia, mongodb, play framework

HI I have following data items in mongo db
{ "id" : 950, "name" : "Name 1" },
{ "id" : 951, "name" : "name 2" }
I have tried mapping id as both Integer and String.
and I used morphia + play to connect mongodb and used DAO of morphia.
I need to do a search by id like (in sql where id like '95%' ) and get the result as list.
List pList = ds.createQuery(Person.class).field("id").startsWith("95").asList(); // this is not working
Any ideas how get this done ??
Having already answered on the play mailing list and the morphia list, i'll answer here so others will see it, too. startsWith() is a text based operation. It doesn't work against numbers. you'll have to use a greaterThan/lessThan query for range checking.

Mongodb - combine data from two collections

I know this has been covered quite a lot on here, however, i'm very new to MongoDB and am struggling with applying answers i've found to my situation.
In short, I have two collections 'total_by_country_and_isrc' which is the output from a MapReduce function and 'asset_report' which contains an asset_id not present in the 'total_by_country_and_isrc' collection or the original raw data collection this was MapReduced from.
An example of the data in 'total_by_country_and_isrc' is:
{ "_id" : { "custom_id" : 4748532, "isrc" : "GBCEJ0100080",
"country" : "AE" }, "value" : 0 }
And an example of the data in the 'asset_report' is:
{ "_id" : ObjectId("51824ef016f3edbb14ef5eae"), "Asset ID" :
"A836656134476364", "Asset Type" : "Web", "Metadata Origination" :
"Unknown", "Custom ID" : "4748532", "ISRC" : "", }
I'd like to end up with the following ('total_by_country_and_isrc_with_asset_id'):
{ "_id" : { "Asset ID" : "A836656134476364", "custom_id" : 4748532,
"isrc" : "GBCEJ0100080", "country" : "AE" }, "value" : 0 }
I know how I would approach with in a relational database but I really want to try and get this working in Mongo as i'm dealing with some pretty large collections and feel Mongo is the right tool for the job.
Can anyone offer some guidance here?
I think you want to use the "reduce" output action: Output to a Collection with an Action. You'll need to regenerate total_by_country_and_isrc, because it doesn't look like asset_report has the fields it needs to generate the keys you already have in total_by_country_and_isrc – so "joining" the data is impossible.
First, write a map method that is capable of generating the same keys from the original collection (used to generate total_by_country_and_isrc) and also from the asset_report collection. Think of these keys as the "join" fields.
Next, map and reduce your original collection to create total_by_country_and_isrc with the correct keys.
Finally, map asset_report with the same method you used to generate total_by_country_and_isrc, but use a reduce function that can be used to reduce the intersection (by key) of this mapped data from asset_report and the data in total_by_country_and_isrc.