How to find the string from string array in firestore - string

I have a list of documents and each document has a field of a string array named "fav", it has more than 50k emails, there are almost 1000 documents and in each document's "fav" array has variable length including 50k, 20k,10, etc. I was fetching all documents
Firestore.instance.collection("save").snapshots();
through StreamBuilder
StreamBuilder(
stream: Firestore.instance.collection("save").snapshots();,
builder: (context, snapshot) {
if (!snapshot.hasData)
return Text("Loading Data.............");
else {
listdata = snapshot.data.documents;
return _buildBody(snapshot.data.documents);
}
},
)
Now How I can search my required email from each document's field "fav"? I have to perform an operation after finding the required id in the array locally.

The question is not very clear, but for my understanding, this is what you are looking for
Firestore.instance.collection('save')
.where('fav', arrayContains: 'abc#gmail.com').snapshots()

The question is not very clear, but for my understanding, you want to find one e-mail in the array field. This array is contained on each document, and all the documents are "streamed" in a collection of snapshots.
Contains Method: https://api.dartlang.org/stable/2.0.0/dart-core/Iterable/contains.html
bool contains (
Object element
)
Returns true if the collection contains an element equal to element.
This operation will check each element in order for being equal to element, unless it has a more efficient way to find an element equal to element.
The equality used to determine whether element is equal to an element of the iterable defaults to the Object.== of the element.
Some types of iterable may have a different equality used for its elements. For example, a Set may have a custom equality (see Set.identity) that its contains uses. Likewise the Iterable returned by a Map.keys call should use the same equality that the Map uses for keys.
Implementation
bool contains(Object element) {
for (E e in this) {
if (e == element) return true;
}
return false;
}

Related

Update specific field in an array of object in a MongoDb Document

I have a document with that format :
{
"field1":"string",
"field2":123,
"field3":
[
{
"subField1":"string",
"subField2": object,
// other fields after
},
{
"subField1":"string",
"subField2": object,
// other fields after
},
// other fields after
]
// other fields after
}
I want to update at once the field3.$.subField2 field only, with a different value in each of the elements of the array composing field3.
Does anyone knows how to properly do it ?
One reason I want to do this is I have several asynchronous operations that are meant to update differents fields of the array field, and I have concurrency issues...
I tried with findOneAndUpdate(query, $set{"field3.$.subField2": arrayOfValues}) but it does not works, it seems I can only pass one single value that would be set to each element of the array (all the same).
arrayOfValues would be of course an array with only the values I want with the matching indexes and same size of the document's array.

How do you query a CouchDB view that emits complex keys?

Given a CouchDB view that emits keys of the following format:
[ "part1", { "property": "part2" } ]
How can you find all documents with a given value for part1?
If part2 was a simple string rather than an object startkey=["part1"]&endkey=["part1",{}] would work. The CouchDB docs state the following:
The query startkey=["foo"]&endkey=["foo",{}] will match most array keys with "foo" in the first element, such as ["foo","bar"] and ["foo",["bar","baz"]]. However it will not match ["foo",{"an":"object"}]
Unfortunately, the documentation doesn't offer any suggestion on how to deal with such keys.
The second element of your endkey value needs to be an object that collates after any possible value of the second element of your key. Objects are compared by property-by-property (for example, {"a":1} < {"a":2} < {"b":1}) so the best way to do this is to set the first property name in your endkey to a very large value:
startkey=["part1"]&endkey=["part1", { "\uFFF0": false }]
The property name of \uFFF0 should collate after any other property names in the second key element, and even works when the second element is an empty object or has more than one property.

Linq query to return boolean

I am inserting data into my entity table using .AddObject(). The object is of the entity table's type. The object is eventStudent, it has string eventStudent.ID, bool eventStudent.StudentPresent, bool eventStudent.ParentPresent.
The students are a list of strings containing student ids. Their presence at the event is in another object called attendees, consisting of String studentID, bool studentPresent and bool parentPresent. Only student id's that have true for StudentPresent and/or ParentPresent are in the attendees list.
As I load up my eventStudent object, I need to set StudentPresent and ParentPresent. This is what I came up with:
foreach (StudentMinimum student in students)
{
eventStudent.StudentPresent = (from a in attendees
where a.StudentID.Contains(student.StudentID)
&& a.StudentPresent
select a.StudentPresent);
}
I receive the error cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'bool'
How can I improve my query so eventStudent.StudentPresent is set to either True or False?
The compiler doesn't know what type will be returned from your query as you haven't explicitly casted it to a type. As a result, it gets a generic IEnumerable type (there could be many records returned right? Hence the IEnumerable. And those records could each be of any type, hence the generic type).
So if the data in your DB were bad and you got multiple records back, converting:
StudentPresent
true
false
false
to a bool is not going to happen. There are a few ways you could get around this. Personally, I'd do something like
var studentPresent = (from a in attendees
where a.StudentID.Contains(student.StudentID)
&& a.StudentPresent
select a.StudentPresent).FirstOrDefault();
eventStudent.StudentPresent = (bool)studentPresent;
Well, actually, I'd use a lambda query instead but that's just personal preference.

What is in the reduce function arguments in CouchDB?

I understand that the reduce function is supposed to somewhat combine the results of the map function but what exactly is passed to the reduce function?
function(keys, values){
// what's in keys?
// what's in values?
}
I tried to explore this in the Futon temporary view builder but all I got were reduce_overflow_errors. So I can't even print the keys or values arguments to try to understand what they look like.
Thanks for your help.
Edit:
My problem is the following. I'm using the temporary view builder of Futon.
I have a set of document representing text files (it's for a script I want to use to make translation of documents easier).
text_file:
id // the id of the text file is its path on the file system
I also have some documents that represent text fragments appearing in the said files, and their position in each file.
text_fragment:
id
file_id // correspond to a text_file document
position
I'd like to get for each text_file, a list of the text fragments that appear in the said file.
Update
Note on JavaScript API change: Prior to Tue, 20 May 2008 (Subversion revision r658405) the function to emit a row to the map index, was named "map". It has now been changed to "emit".
That's the reason why there is mapused instead of emitit was renamed. Sorry I corrected my code to be valid in the recent version of CouchDB.
Edit
I think what you are looking for is a has-many relationship or a join in sql db language. Here is a blog article by Christopher Lenz that describes exactly what your options are for this kind of scenario in CouchDB.
In the last part there is a technique described that you can use for the list you want.
You need a map function of the following format
function(doc) {
if (doc.type == "text_file") {
emit([doc._id, 0], doc);
} else if (doc.type == "text_fragment") {
emit([doc.file_id, 1], doc);
}
}
Now you can query the view in the following way:
my_view?startkey=["text_file_id"]&endkey;=["text_file_id", 2]
This gives you a list of the form
text_file
text_fragement_1
text_fragement_2
..
Old Answer
Directly from the CouchDB Wiki
function (key, values, rereduce) {
return sum(values);
}
Reduce functions are passed three arguments in the order key, values and rereduce
Reduce functions must handle two cases:
When rereduce is false:
key will be an array whose elements are arrays of the form [key,id], where key is a key emitted by the map function and id is that of the document from which the key was generated.
values will be an array of the values emitted for the respective elements in keys
i.e. reduce([ [key1,id1], [key2,id2], [key3,id3] ], [value1,value2,value3], false)
When rereduce is true:
key will be null
values will be an array of values returned by previous calls to the reduce function
i.e. reduce(null, [intermediate1,intermediate2,intermediate3], true)
Reduce functions should return a single value, suitable for both the value field of the final view and as a member of the values array passed to the reduce function.

Efficient way to search object from list of object in c#

I have a list which contains more than 75 thousand object. To search item from list currently I am using following code.
from nd in this.m_ListNodes
where
nd.Label == SearchValue.ToString()
select
nd;
Is this code is efficient?
How often do you need to search the same list? If you're only searching once, you might as well do a straight linear search - although you can make your current code slightly more efficient by calling SearchValue.ToString() once before the query.
If you're going to perform this search on the same list multiple times, you should either build a Lookup or a Dictionary:
var lookup = m_ListNodes.ToLookup(nd => nd.Label);
or
var dictionary = m_ListNodes.ToDictionary(nd => nd.Label);
Use a dictionary if there's exactly one entry per label; use a lookup if there may be multiple matches.
To use these, for a lookup:
var results = lookup[SearchValue.ToString()];
// results will now contain all the matching results
or for a dictionary:
WhateverType result;
if (dictionary.TryGetValue(SearchValue.ToString(), out result))
{
// Result found, stored in the result variable
}
else
{
// No such item
}
No. It would be better if you used a Dictionary or a HashSet with the label as the key. In your case a Dictionary is the better choice:
var dictionary = new Dictionary<string, IList<Item>>();
// somehow fill dictionary
IList<Item> result;
if(!dictionary.TryGetValue(SearchValue.ToString(), out result)
{
// if you need an empty list
// instead of null, if the SearchValue isn't in the dictionary
result = new List<Item>();
}
// result contains all items that have the key SearchValue

Resources