Case in-sensitive search in array fields - arrays

I want to store an array to Neo4j db, Before knowing array field types, I was stored my array as an comma separated text field and used regex for find nodes that have an specific item!
Now i want to save array as an array field but i cant write a case insensitive condition with "IN" keyword!
There is my Regex for finding in cs-text field:
MATCH (user:USER)-[:MEMBER_OF]->(group:SOME_GROUP) where
group.resources =~ "(?i)(?:.*,|^)one_resource(?:,.*|$)"
RETURN group
My stored data was like this:
One_Resource,Another_Resource,...
And result was correct but i have some issues on retrieving this model and array field is better in retrieve.
Do you have any suggesting or method to solve this issue?
This is my Cypher for array field:
MATCH (node {hid:"abc"})
SET node.array_field = ["Foo","Bar","Baz","BaG"]
And finding with this:
MATCH (node) WHERE "foo" IN node.array_field RETURN node
But this is case sensitive :(
Thanks

I founded my answer in the book: Learning Cypher
Must use ANY (...IN...WHERE...) in WHERE clause:
MATCH (node)
WHERE ANY ( item IN node.array_field WHERE item =~ "(?i)foo" )
RETURN node
Now can use Regex to finding wanted node.
There are four collection predicates. They are as follows:
ANY: This predicate returns TRUE if at least one item in the collection adheres
to the expression
ALL: This predicate returns TRUE if all items in the collection adhere to the rule
NONE: This predicate returns TRUE if no item in the collection follows the rule
SINGLE: This predicate returns TRUE if exactly one item follows the rule
If we want all books tagged as NoSQL but not as Neo4j, we can use the NONE predicate
as follows:
MATCH (b:Book)
WHERE ANY ( tag IN b.tags WHERE tag = 'nosql' )
AND NONE ( tag in b.tags WHERE tag = 'neo4j' )
RETURN b.title,b.tags

Related

NOT IN within a cypher query

I'm attempting to find all values that match any item within a list of values within cypher. Similar to a SQL query with in and not in. I also want to find all values that are not in the list in a different query. The idea is I want to assign a property to each node that is binary and indicates whether the name of the node is within the predefined list.
I've tried the following code blocks:
MATCH (temp:APP) - [] -> (temp2:EMAIL_DOMAIN)
WHERE NOT temp2.Name IN ['GMAIL.COM', 'YAHOO.COM', 'OUTLOOK.COM', 'ICLOUD.COM', 'LIVE.COM']
RETURN temp
This block returns nothing, but should return a rather large amount of data.
MATCH (temp:APP) - [] -> (temp2:EMAIL_DOMAIN)
WHERE temp2.Name NOT IN ['GMAIL.COM', 'YAHOO.COM', 'OUTLOOK.COM', 'ICLOUD.COM', 'LIVE.COM']
RETURN temp
This code block returns an error in relation to the NOT's position. Does anyone know the correct syntax for this statement? I've looked around online and in the neo4j documentation, but there are a lot of conflicting ideas with version changes. Thanks in advance!
Neo4j is case sensitive so you need to check the data to ensure that the EMAIL_DOMAIN.Name is all upper case. If Name is mixed case, you can convert the name using toUpper(). If Name is all lower case, then you need to convert the values in your query.
MATCH (temp:APP) - [] -> (temp2:EMAIL_DOMAIN)
WHERE NOT toUpper(temp2.Name) IN ['GMAIL.COM', 'YAHOO.COM', 'OUTLOOK.COM', 'ICLOUD.COM', 'LIVE.COM']
RETURN temp

How to use arrayContains with list in FlutterFire that returns documents with ONLY the values in the given list

Example:
List<String> vehicleList = ['bus', 'plane']
var tarifRef = _firestore
.collection("vehicles")
.where("models", arrayContains: vehicleList );
Is there a way I can return documents that contain only the items in the vehicleList ?
What you're trying to do can only work with Firestore if the items in the list always have a predictable order. Typically you do this by making sure they are sorted by their natural sort order before you write the document, and in the list that you pass to the query. If the lists are identical, you can simply use a normal equality filter to compare them. If the lists contain the same strings, but they are not in the same order, then the equality check won't match them.
See also:
How do I query Cloud Firestore for an array that matches all values, but in any order?

Testing to see if a inputted value is present in an array Mongodb

So i have a small test collection that has this format...
Sample Data
I have created a simple query that returns an array with all the ids..
All_Ids = db.Test_Collection.find({}, {_id:1}).map(function(item){ return item._id; })
[ 98800754, 15301328, 76812898 ]
And i Want to take in an inputted id and check to see if that inputted value is present in the array..
here was my initial attempt..
> query_Figure = 98800754
98800754
> db.Test_Collection.find({query_Figure: {$in: All_Ids}})
I tried using the $in operator to find that specific value.. with the array and specific id to be searched as variables, but had no luck as the query returned nothing, when the value im searching for is clearly in the array
As you can tell I am a newbie and would appreciate some help in improving the query!
$in operator returns the documents in which value of the specified field is present in the array.
In your case, since query_Figure is not a field in any of your documents, your query returns no matching documents.
If you just want to check if the input id is present in the All_Ids array, then you don't need a query. Just use Array.prototype.includes()
const exists = All_Ids.includes(query_Figure);

Group structs by exploding map<struct> into a list and filtering with sameElement

Can vespa group on <map: string,struct> with a clause on struct.k1=x AND struct.k2=y and only getting the counts with how many structs match (not documents!, cause a document may have multiple structs that match) ?
So it will explode all struct in a list using where struct.k1=x AND struct.k2=y and return a group of map.
Just like you can filter with sameElement, in this case you list the structs, do a sameElement filter, and then group by struct.k3
Does that make sense ?
Thank you
edit: an example is in Postgresql. unnest() can be used on array while json_each() can be used on json to convert them to row
Reference:
https://www.postgresql.org/docs/current/functions-array.html
https://www.postgresql.org/docs/11/functions-json.html
Vespa's grouping framework will work on the all the map elements in the document and not only the ones that matched the sameElement query item. Similar if you have a simple field foo array<string>{} grouping will operate over all elements in the array and not only the element(s) which matched the query.

Sitecore Solr Search by Multilist with Values from Another Multilist

I have a set of product items. Each product item has a multilist field that points to a set of product type items. When on a product page, I want to show a paged list of related items. These should be items that share a product type with the currently selected item. I'm running into some trouble because products can have multiple types. I need to split the type list on the current item and check that against the list of products in an expression. For some reason split and contains are throwing runtime exceptions and I can't really figure out why. I saw some things about the predicate builder being used for dynamic queries and I will try to use that with what I currently have but I'd like to know why this can't be done straight in the where clause.
Another issue I ran into is that the list of ids stored in solr are being stripped of their '{', '}', and '-' characters.
If you are already on the product page I assume you already have the product item and that product item should have a "ProductType" multilist field. You can use Sitecore.Data.Fields.MultilistFiled to avoid worrying about have to split the raw values.
You can then use Sitecore's Predicate Builder to build out your search predicate, which I assume you want to find all products that have one similar product type. You should adjust this search logic as needed. I am using the ObjectIndexerKey (see more here -> http://www.sitecore.net/Learn/Blogs/Technical-Blogs/Sitecore-7-Development-Team/Posts/2013/05/Sitecore-7-Predicate-Builder.aspx) to go after a named field, but you should build out a proper search model and actually define ProductTypes as a List< ID> or something similar. You may need to add other conditions to the search predicate as well such as path or templateid to limit your results. After that you can just execute the search and consume the results.
As far as Solr stripping the special characters, this is expected behavior based on the Analyzer used on the field. Sitecore and Solr will apply the proper query time analyzers to match things up so you shouldn't have to worry about formatting as long as the proper types are used.
var pred = PredicateBuilder.True<SearchResultItem>();
Sitecore.Data.Fields.MultilistField multilistField = Sitecore.Context.Item.Fields["ProductTypes"];
if (multilistField != null)
{
foreach (ID id in multilistField.TargetIDs)
{
pred = pred.Or(x => ((ID)x[(ObjectIndexerKey)"ProductType"]).Contains(id);
}
}
ISearchIndex _searchIndex = ContentSearchManager.GetIndex("sitecore_master_index"); // change to proper search index
using (var context = _searchIndex.CreateSearchContext())
{
var relatedProducts = context.GetQueryable<SearchResultItemModel>().Where(pred);
foreach(var relatedProduct in relatedProducts)
{
// do something here with search results
}
}
Just an Improvement to #Matt Gartman code,
The error (ID doesn't contain a definition for Contains) which keeps popping up is because .Contains is not a functionality of Type ID, I recommend you to Cast it in string type as below
foreach (ID id in multilistField.TargetIDs)
{
pred = pred.Or(x => (Convert.ToString((ID)x[(ObjectIndexerKey)"ProductType"]).Contains(id.toString())));
}

Resources