Firestore: Query by item in array - javascript

I have documents with field (of array type) for period (from, to):
and I would like to filter documents by item in array of "period" field ... for example:
where('period.0', '>=', startOfYear(new Date()))
but it seems that this doesn't work ...
For example if period is a Map instead of Array, then this thing works:
where('period.start', '>=', startOfYear(new Date()))
But, I store this as an array, because output of UI component is an array and I don't have to map array to object, and later from object for array.
So the question is why this doesn't work with array, and if there is any plan, that this will be supported for arrays to?

There is no operator to filter based on an item at a specific index in an array. If you need that, as you already said, you will need to put the relevant value from the array in a separate field and filter on that.
There are currently no plans to add such an operation, but you can always weigh in with a feature request.

Related

How can I use filter() to find multiple items from a list of Ids?

I'm attempting fetch multiple items by an id property based on a list of ids. To give an example lets use the function below.
findItems(idList: string[]){
let fetchedItems: SomeType[] = [];
idList.forEach(a=>{
fetchedItems.push(DATASOURCE.find(b=> b.id === a));
}
return fetchedItems;
}
As you can see this function takes a list of strings and uses a forEach() method to individually find each item and push it to the fetchedItems array, which means if there's 10 items in that list there will be 10 consecutive calls to the same database.
Looking further into this curiosity it hit me that filter() is designed to do this exact thing. I looked at the documentation on MDN and googled around a bit but I guess I don't know what to specifically search for to get the results I need to study into. Can anyone show me how this can be done?
Make idList into a Set (for less computational complexity), and then you can .filter on DATASOURCE by whether the id is included in the set:
findItems(idList: string[]){
const ids = new Set(idList);
return DATASOURCE.filter(({ id }) => ids.has(id));
}
This assumes that you don't have multiple items in DATASOURCE with duplicate IDs.
Set.has has O(1) complexity, whereas array methods like .find (or .includes, etc) have O(n) complexity.
How about
findItems(idList: string[]){
return DATASOURCE.filter(data => idList.includes(data.id));
}

Chai - Expect an object to have deep property of an array ignore order

I need to check if the payment has a property named transactions with expected values:
expect(payment).to.have.deep.property('transactions', [
TRANSACTION_ID_1,
TRANSACTION_ID_2,
]);
As the order of transactions is not specified, the test doesn't pass all the time.
How can I solve the problem without changing the test structure?
Note: I've found deep-equal-in-any-order plugin, but it seems it doesn't help.
Iterate through array and check if it includes each item.
[TRANSACTION_ID_1, TRANSACTION_ID_2].forEach(id => {
expect(payment).to.have.deep.property('transactions').that.includes(id);
});
If you need to check transactions is unordered array of expected IDs, then check for the length as well.
expect(payment).to.have.deep.property('transactions').that.has.lengthOf(2);
When transactions has all of the expected ids and has same length of expected ids, then it equals to the expected ids when ordered properly.

Push to an array if id value is not found

I've a little array problem I'm going round and round in loops with.
I have a number of check boxes, each checkbox has a specific object.
On checking a checkbox I want to iterate over the array and if the id of the checkbox (object) does not match any other items in the array, push to the array.
I have the following, which pushes the checkbox object for every item that doesn't match it's id. So I end up with multiple objects of the same ID.
mapMarkers.map(marker => {
if(markerID !== marker[0].id) {
mapMarkers.push(markerObject)
};
});
Any help to get my thinking on this straight would be appreciated.
For context here's the project its from. Lines 281
https://codepen.io/sharperwebdev/pen/PQvMqR?editors=0011
The Array#filter method would be more appropriate for this. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
const filteredMarkers = mapMarkers.filter(marker => markerID !== marker.id);
Then use filteredMarkers (mapMarkers isn't mutated, which is a better practice).

Is it possible to sort indexedDB result set without temp array i.e. by using db queries

Is it possible to sort the result set produced by indexedDB without using push
operation in the temporary array.So that no manual looping is involved.
In some cases this is possible using indexes. For example, if you have records of the form {team_id: 123, name: 'alice'} and wanted to select by team_id then sort by name you could construct an index on [team_id, name], and call openCursor() (or getAll() if supported) with a key range IDBKeyRange.bound([id], [id+1], false, true) to get all records with team_id == id and sorted by name.
If you can't construct an index for this - e.g. if the sort comparison function you want doesn't match IDB key ordering, or if your selection can't be expressed simply as a range - then you'll need to use a temp array.

Search for elements that have a particular attribute in array

One element of my mongo collection has the following schema (and represents one poker hand).
{
"players":
[
{"active":true,"seat":1,"stack":1769,"screenName":"schla"},
{"active":true,"seat":3,"stack":2000,"screenName":"galgegla"},
{"active":true,"seat":4,"stack":483,"screenName":"khrier"},
{"active":true,"seat":5,"stack":2813,"screenName":"frrou4535"},
{"active":true,"seat":6,"stack":4002,"screenName":"Guabounai"}
],
"rounds":[],
"gameNum":"1030564654564",
"time":"2013/12/21 21:12:03"
}
I'd like to search for all hands in my collection that have at least one time the player with screenName "galgegla" inside the players array.
Supposing your collection is called 'hands', you can do following:
db.hands.find( { 'players.screenName': 'galgegla' } )
See example under 'Match a Field Without Specifying Array Index' here: http://docs.mongodb.org/manual/tutorial/query-documents/#match-a-field-without-specifying-array-index
Try this:
a.filter(function(arr){
return arr.players.filter(function(player){
return player.screenName == 'galgegla';
}).length;
});
Assuming a is a array of those objects.
It filters the array of objects based on weather or not a filter on the object's players array returns any results.
... But of course I didn't consider mongo's native functionality, so the other answer'd be more effective. (But possibly not as efficient)

Categories