Lucene.net search on filed that is a list - lucene.net

tried [this approach][1] but did not work for me
[1]: https://stackoverflow.com/questions/1917405/lucene-net-search-list
I have a field that is a coma separated list of ids... like 500, 212, 303, ...etc.
When I'm indexing/search I'm using an PerFieldAnalyzerWrapper .. and for that field I already tried whitespace and standaranalyzer..
Also tried replacing the coma for a white space, separate numbers _ (leaving 500, 212, and also add it when searching) and adding a wildcard on the search.
Currently on search, while building the query I tried the linked solution and used
private Query GetPopIDQuery(string popID)
{
StandardAnalyzer analyzer = new StandardAnalyzer(LuceneVersion.LUCENE_48); //use standard analyzer
QueryParser parser = new QueryParser(LuceneVersion.LUCENE_48, "popfield", analyzer); //search inside category field
Query query = parser.Parse(popID); //get the query
return query;
}
So no luck yet... when I search for an ID that should be on tthat list... I get empty results.... is there a best aproach on handling index/search of a filed that has a list of numbers?
Thanks!

Related

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)

How to override Ag Grid QuickFilter to receive exact match results?

By default Ag Grid Quick Filter function return rows that contains search string. For example if I type "30 June" in the searchbox, quick filter will also return rows that contains "30 cars were sold by 2 June" text. How can I override default behavior to receive only rows that exactly match my search string?
What I did was the following:
In the search itself, I removed the spaces from the search criteria:
this.gridApi.setQuickFilter(event.toLowerCase().replace(" ", ""));
In each column that I wanted an exact match, I added this code in the column definition:
getQuickFilterText: (params) => { return params.value && params.value.toLowerCase().replace(" ", "");}
(That is the override method for search. See here for more details: https://www.ag-grid.com/angular-data-grid/filter-quick/)
It seems to be working for me.
To achieve the exact match results column wise, You have to do these two things :
Remove cacheQuickFilter property from your default column definition object in gridOptions as caching convert all the columns data into a string separated by backward slash. That's the reason it will not be able to search column by column.
Add getQuickFilterText function in each column definition and add a condition for a exact match else return an empty string.
getQuickFilterText: params => {
return (params.value === <quick filter value>) ? params.value : ''
}
Now the tricky part here is how to access quick filter value inside getQuickFilterText function. You can achieve this in two ways :
Assign an id to quick filter search element and then access it's value using document.getElementById('quick-filter').value
Store the quick filter search value on change and put into a store state or service and then access that inside getQuickFilterText function.

Lucene.net search doesn't return names

I am using WhitespaceAnalyzer to index some values.
document.AddField("transcript", <transcript value>, Lucene.Net.Documents.Field.Store.YES, Lucene.Net.Documents.Field.Index.ANALYZED);
and do a search like follows
booleanMiniQuery.Add(new TermQuery(new Term("transcript", <search value>)), rule);
when contains some names like baileys OR bailey doing search for that doesn't return any result.
Can any one tell what I am doing wrong
Before you search for a term in Lucene, you need to analyze the string with the same analyzer that you indexed that text with (in this case WhiteSpaceAnalyzer).
I would recommend using the QueryParser to make this process a lot easier, for eample:
var qParser = New QueryParsers.Classic.QueryParser(Version, "transcript", WhiteSpaceAnalyzer) var termQuery = qParser.parse(<search value>)
booleanMiniQuery.Add(termQuery, rule);

Exclude field from full-text search

I need to do the full text search in the MongoDB (version 2.4). I use the following fragment of code.
DBObject textSearchCommand = new BasicDBObject();
textSearchCommand.put("text", "profile");
textSearchCommand.put("search", pattern);
textSearchCommand.put("limit", searchLimit);
textSearchCommand.put("filter",new BasicDBObject("personInfo", new BasicDBObject("$ne",null)));
CommandResult commandResult = mongoTemplate.executeCommand(textSearchCommand);
BasicDBList results = (BasicDBList) commandResult.get("results");
It works well but I want to exclude one field (person picture data) from the text search.
Note: I don't want to exclude this field from the result. I want that MongoDB does not search in this field.
Which fields to search in is determined when you create the text index. When you only want the text index to apply to selected fields, you need to provide these fields at creation like this for example:
db.articles.createIndex(
{
title: "text",
synopsis: "text",
content: "text",
tags: "text"
}
)
When this is not an option for some reason (like when you don't know all possible field names which might be relevant for text search), an (admittedly dirty) workaround could be to store the non-searchable content in a different data-type than a string, for example as binary data.

How to implement search using Query Builder API for partial search text in CQ/AEM

I have a requirement to fetch search results based on partial text match. For example, if there is a node under products say "apple-iphone-6" and the user enters "iphone" text in the searchbox, I should still be able to fetch the result.
I tried the below query on querybuilder and it worked:
http://localhost:4502/bin/querybuilder.json?path=/etc/commerce/products&type=nt:unstructured&nodename=*iphone*
But, how to implement this programatically for the *iphone* part? I am creating a query using the predicates as follows
String searchTerm = "iphone";
map.put("path", "/etc/commerce/products");
map.put("type", "nt:unstructured");
map.put("nodename", searchTerm);
Query query = queryBuilder.createQuery(PredicateGroup.create(map), session);
SearchResult result = query.getResult();
But I do not get any results, reason being, the node name(apple-iphone-6) does not exactly match the search term (iphone).
But the same thing works fine in case I append * to the nodename value which then implements partial text based search in the querybuilder example. What change should I do in the code to get results based on partial node name matches?
You already have found the solution on your own, the NodenamePredicateEvaluator accepts wildcard arguments, so you would need to surround the search term with wildcards, for example like this:
String searchTerm = "iphone";
...
map.put("nodename", "*" + searchTerm + "*");
in this case "like" opration can be used:
EX-> patial text serach for jcr:title
map.put("group.1_property", "fn:lower-case(#jcr:content/jcr:title)");
map.put("group.1_property.value", "%"+fulltextSearchTerm + "%");
map.put("group.1_property.operation", "like");
For just the nodename the answer posted is correct, but if you want to search inside properties as well then :
map.put("fulltext","*"+searchTetm +"*");
map.put("fulltext.relPath","jcr:content");