Force query to match more than one attribute - algolia

I have an index that includes these attributes: Name, Address, City, State, Zip
I want to do a allOptional search but I don't want city, state, or zip to match without name or address also matching. So a search query of McDonalds would match all McDonalds in every city/state, McDonalds Chicago would return all McDonalds in Chicago and McDonalds 60007 would return all McDonalds in the zip code 60007.
But a search query of Chicago or Chicago IL would return 0 results.
I've been reading the filters and facets documentation and I think this should be possible with a filter but I can't seem to figure out how.

You can solve this issue by post processing results after you have received them, before rendering them.
You can use the _highlightResult data in the hits response to filter out hits in which the query isn't matched in certain attributes.
For instance to remove hits where the query isn't matched in either the name or address attribute:
var displayedResults = response.hits.filter(hit => {
return hit._highlightResult.name.matchLevel !== 'none' || hit._highlightResult.address.matchLevel !== 'none';
});

Related

How to display dataframe inside an if else statement?

I am quite new to programming and currently self studying jupyter notebook for data analytics. I just need to know whether we can execute a data frame object inside and if else statement.
First I read city name from user and check whether the given city is in the data frame. And then filter the dataframe according to the value given by user. If city is not there, print that the city is not here. I need to know is there any method to execute this in a good way. This was my silly try. If someone can help, would be a big help
cityname = input("Input the name of the city to see the data required")
if totaldata['City'].any() == cityname:
totaldataCitywise = totaldata.loc[totaldata['City'] == cityname, :]
totaldataCitywise
else:
print('The city is not in the list')`

Flutter Firestore only return user overview ListTile when field contains specific words

I am listing users in a CustomScrollView/SliversList,ListTiles. I have a String field in my firestore and only want to return ListTile of a user, where his String field contains specific words (more than 2). For example, the users fields contain: "Apples, Ice, Bananas, Soup, Peaches, e.g...." and i want to list all users which have apples and bananas inside the field. how can i achieve this?
The only way to do it at the moment (with the way you have it set up) is actually pulling the value and doing a string "contains" or splitting the string into an array and check whether the value is within that array, otherwise I'd advise to refactor that field and make it into an array, that way you can perform a native arrayContainsAny against your field.
For you it will look like this (with your current implementation):
// ... after pulling all users' documents
// let's say your field is called 'foodField':
var criteria = 'Banana';
var fieldContent = doc.data()['foodField'];
// you can either do this:
if (fieldContent.toLowerCase().contains(criteria.toLowerCase())) {
// ...
}
// or you can tokenize it depending on your purposes...
var foodTokens = fieldContent.split(',').map((f) => f.toLowerCase());
if (foodTokens.contains(criteria.toLowerCase()) {
// ...
}
If your Firestore field was an array type, then you could've just done that, while querying:
FirebaseFirestore.instance.collection('users').where('foodField', arrayContainsAny: ['Banana', 'Apples'])
Which then would give you only the users whose foodField contain that value.
As you can see from previous questions on querying where text contains a substring, Firestore does not currently support such text searches. The typical solutions are to either perform part of your filtering in your application code as Roman answered, or to integrate a third-party full-text search solution.
In your specific case though, your string seems to be a list of words, so I'd recommend considering to change your data model to an array of the individual values in there:
"foodFields": ["Apples", "Ice", "Banana", "Soup", "Peaches"]
You can then use array field operators in the query.
While there is no array-contains-all operator, using array-contains you can at least filter on one value in the database, and with array-contains-any you can do on OR like condition.
Another data model would be to store the individual values in a map field with value true for each of them:
"foodFields": {
"Apples": true,
"Ice": true,
"Banana": true,
"Soup": true,
"Peaches": true
}
With such a structure you can perform an AND like query with:
collectionRef
.where('foodFields.Apples', isEqualTo: true)
.where('foodFields.Bananas', isEqualTo: true)

Strapi - How to GET data sorted based on relation property?

I have an Articles table and it has a relation with the Authors table. Each author has a name property. I want to make a GET request for the articles and receive the articles sorted based on their author's name.
When I use _sort=author in the url parameters, I get the articles sorted based on the author object's ID.
When I use _sort=author.name in the url parameters, I get the articles in a seemingly random order but definitely not based on author.name.
How can I get the data sorted based on author.name?
I use mongoDB as my database.
That is the default behavior of _sort. However, you can simply accomplish this by overriding the find method in api/article/services/article.js to sort by Author's name like so:
module.exports = {
async find(params, populate) {
let result = await strapi.query('article').find(params, populate);
if (params._sort == 'author')
return result.sort((a, b) => (a.author.name > b.author.name) ? 1 : -1);
return result;
},
}
Check the documentation for customizing services to get more info: https://strapi.io/documentation/v3.x/concepts/services.html#concept

MongoDB Complex Query with Java

We have following structure in MongoDB documents.
{
"id":"1111",
"keys":[
{
"name":"Country",
"value":"USA"
},
{
"name":"City",
"value":"LongIsland"
},
{
"name":"State",
"value":"NewYork"
}
]
}
Now using Springframework Query object, I figured out a way to pull the details using below syntax
query.addCriteria(
Criteria.where("keys.value").is(countryparam).
andOperator(
Criteria.where("keys.value").is(stateparam)
)
);
Two issue with this query model.
First issue is it is irrelevant if countryparam and stateparam are actually meant to match Country key name and State key name respectively. If just the values matches, the query returns the document. Means, if I have Country and City params, this just works if user passes Country and City values, even if they are swapped. So how can I exactly compare City to cityparam and State to Stateparam?
More complexity is if I have to extract the document basing on multiple key value pairs, I should be correspondingly able to match key name with respective value and query the document. How can I do this?
Thanks in advance!

Is there a way to update a database field based on a list?

Using JPA, I have a list of entries from my database :
User(id, firstname, lastname, email)
That I get by doing:
List<User> users = User.find("lastname = ?", "smith");
And I'd like to update all in one request, by doing something like this :
"UPDATE USER SET email = null IN :list"
and then set the parameter "list" to users
Is it possible? if so, how?
Thanks for your help :)
Well, you could embed the query that you used to obtain list in the where clause of the update.
UPDATE User a SET a.email = null
WHERE user IN (SELECT b FROM User b WHERE lastName = :?)
By doing this you'd be doing the query to search the list and the update in single update query.
How do you like that? Do you think this could work?
-EDIT-
Since you want to use the original list of items instead of a list just retrieved from the database, you can still ensure you build the original list like this
UPDATE User a SET a.email = null
WHERE user IN (SELECT b FROM User b WHERE lastName IN(:originalList))
Then when you invoke it, you can do something like this:
Collection<String> originalList = Arrays.asList("Kenobi", "Skywalker", "Windu");
query.setParameter("originalList", originalList);
By this, you can still ensure the query will only contain items in your original list and not any possible new item from the database, provided that that last name is a candidate key in the database, otherwise I would recommend that you use the ID for the subquery instend of the last name.
if you have jpa+hibernate you can use entityManager.createQuery() for creating hql query
like that:
String hql = "UPDATE Supplier SET name = :newName WHERE name IN :name";
entityManager.createQuery(hql);