How can I index and query nested arrays in Dexie.js? - dexie

The docs for MultiEntry indexes say any Indexable Type can be used.
Arrays are indexable types. Therefore it should be possible to index arrays of arrays and so on, right?
However, I couldn't find any examples or figure out how to query these.
Basically, what I want is something like:
var db = new Dexie('dbname');
db.version(1).stores({
books: 'id, author, name, *properties'
});
db.books.put({
id: 1,
name: 'Human Action',
author: 'Ludwig von Mises',
properties: [['language', 'english'], ['subject', 'philosophy'], ['subject', 'economics']]
});
Then be able to find a book that has an economics subject.

That's right. Each entry in the properties array is an array of two strings - and that inner array itself is indexable and may act as an indexable entry.
So to find all books that has subject economics, do
db.books.where({properties: ['subject', 'economics']}).toArray()
or the equivalent form:
db.books
.where('properties')
.equals(['subject', 'economics'])
.toArray();

Related

Loopback4 filter inside the scope return list still

I'm using lb4
I have some problems here, I try to find the list with where conditions inside the scope with pagination.
const teacherWithStudents = await this.teacherRepository.find({limit:10,skip:0,
include: [{
relation: "student",
scope: {
where: { "name": "some random name here" },
}
}]
})
The expected teacher's array is : [] (because I searched a random string in student name which is not in DB)
but I got teachers to array without student like this: [{teacherId:1,teacherName:"Stella"}{teacherId:2,teacherName:"Mery"}]
if I filter student names if no teacher has a student that I filtered I need an empty array but I get only a teacher.
I hope I explained the issue in detail.
Thanks in advance
This is expected as the parent and relation queries should be perceived as two separate queries.
First, the list of teachers based on the parent query are resolved. The IDs of the resolved teachers are then used as a constraint when querying for the list of students.
Both results are then combined together to create the final response.
Loopback uses left join. if you want to find only teachers where student is not null then you have to use inner join with native query.

.net core when I read from appsettings, the sort is changed. Why?

I have this config in appsettings.json:
"CategoriesTypes": [ "Country", "State", "Semester" ],
in the code I read values like:
var array = Configuration.GetSection("CategoriesTypes").AsEnumerable() .Where(o => !string.IsNullOrEmpty(o.Value)).Select(o => o.Value).ToArray()
// output of foreach loop:
"Semester", "State", "Country"
Why The sort is changed?
IEnumerable do not pretend to keep items in order, unless you ask for. And as described in the docs
Methods that are used in a query that returns a sequence of values do not consume the target data until the query object is enumerated.
When you iterate through an IEnumerable it is just navigating to the previous/next item without knowing it in advance. So IEnumerable do not keep items sorted, because sorting requires to enumerate through the whole items in the list.
If you need to sort the list just use Linq extensions OrderBy or OrdrByDescending which will return IOrderedEnumerable<T>.

How can i use hashmaps to query for multiple parameters?

How can I use a hash-table (is it possible ?) to query for multiple parameters belonging to the same object?
Let me explain.
If I have the following array of objects
persons = [{name: "AA"}, {name: "BB"}, {name: "CA"}]
And I want to store them on a hash table, using the name as the value the
hashtable.put(persons[0]); // will compute hash("AA")
hashtable.put(persons[1]); // will compute hash("BB")
hashtable.put(persons[2]); // will compute hash("CA")
This would allow me to query my hashtable by name very fast.
My question is, Is there any implementation of a hash-table that would allow me to query for multiple parameters for more complex objects like this
persons = [{name: "AA", city: "XX"}, {name: "BB", city: "YY"}, {name: "CA", city: "ZZ"}]
For example. Look for names = "AA" and cities = "ZZ"
If hash-tables are not for this type of operations which algorithms or Data structures are the best for this type of operations?
In python you are able to use tuples as keys in your hashmap:
persons = [{name: "AA", city: "XX"}, {name: "BB", city: "YY"}, {name: "CA", city: "ZZ"}]
hashmap = {}
for d in persons:
hashmap[(d["name"], d["city"])] = ...
Then you can query your hashmap like so:
hashmap[(name, city)]
In other languages you should be able to implement something similar (using groups of elements as keys). This may require implementing a custom hash, but hash map is still the correct data structure for this.
Hash tables require complete keys to be known. If a key consists of several fields, and even one is unknown it doesn't work.
Maybe you are looking for something like Partitioned Hash Functions:
http://mlwiki.org/index.php/Partitioned_Hash_Function_Index
Which are used in relational databases that support multidimensional indices.

LINQ syntax - ordering of criteria

I'm trying to understand LINQ syntax and getting stuck. So I've got this line which gets all of the people with the postcode I'm searching for
IQueryable<int> PersonIDsWithThisPostcode = _context.Addresses
.Where(pst => pst.Postcode.Contains(p))
.Select(b => b.PersonID);
This line then only returns people in PersonIDsWithThisPostcode
persons = persons.Where(ps => PersonIDsWithThisPostcode.Contains(ps.PersonID));
I'd have expected it to be something along the lines of this, where you're looking at a container, then checking against a subset of values to see what you want.
persons = persons.Where(ps => ps.PersonID.Contains(PersonIDsWithThisPostcode));
So from a SQL point-of-view I'd think of it something like this
bucket = bucket.Where(bucket.Contains(listoffish));
but it seems to act like this
bucket = bucket.Where(listoffish.Contains(bucket));
I've read through lots of documentation but I can't get my head around this apparently simple notion. Any help to explain this way of thinking would be appreciated.
Thanks
If PersonID is an int you can't use ps.PersonID.Contains because an int is not a collection (or string which would search a substring).
The only correct way is to search your PersonId in a collection which is the PersonIDsWithThisPostcode-query that returns all matching PersonIds.
A single PersonID doesn't contain a collection but a collection of PersonIds contains a single PersonId.
So this is correct, it returns all persons which PersonId is in the other sequence:
persons = persons.Where(ps => PersonIDsWithThisPostcode.Contains(ps.PersonID));
and this not:
persons = persons.Where(ps => ps.PersonID.Contains(PersonIDsWithThisPostcode));
The syntax is reversed in comparison to SQL, which should come as no surprise, considering that C# and SQL are two different languages.
In SQL you place the list on the right, because IN operator reads "item in collection"
WHERE someId IN (100, 102, 113, 200, 219)
In C#, without regard to LINQ, you check if a collection contains an item using code that reads "collection contains item"
myList.Contains(someId);
When you use Contains in LINQ that gets translated to SQL, LINQ provider translates one syntax to the other syntax to shield C# programmers from thinking about the differences.

Comparing two arrays in parse query

How do we find if any element of an array is part of another array in a query?
var followers = []; // Array of Parse User pointers
query.howTo("attending", followers); // attending is an array of User Pointers.
That is, the query should match if any one or more of the elements in followers exists in attending.
query.containsAll matches for all the elements. Is there something like query.containsSome ?
I was pretty sure you can query two arrays. Take a look into the docs to check better.
In case it doesn't, you can use compound queries.
For example, generate an array of queries, based on the array of followers. The [forEach] is a better idea in this case, but I'm supposing here a for loop.
var followers = []; //array of users
var mainQuery = new Parse.Query(YourOtherObject);
//for each one of followers
var orQuery = new Parse.Query(YourOtherObject);
orQuery.equalTo("attending", follower);
mainQuery = Parse.Query.or(mainQuery, orQuery);
This solution might not be performant if your followers areay is too big. But in any case, I still recommend using relations in this case, as you benefit from the inverse, and can get from the users query, where he is present as attending in the other Object.

Resources