Search By Partial word of a sentence in elastic search - c#

I am very new to Elastic Search , I want to search a result based on a partial word of a sentence , like the search string is
"val"
and it should search the result with string value
"value is grater than 100"
but if I am using a query
var searchDescriptor = new SearchDescriptor<ElasticsearchProject>()
searchDescriptor.Query(q =>
q.Wildcard(m => m.OnField(p => p.PNumber).Value(string.Format("*{0}*", searchString)))
);
it will work only for one word string like
"ValueIsGraterThan100"
if I use something like this
var searchDescriptor = new SearchDescriptor<ElasticsearchProject>()
searchDescriptor.Query(q =>
q.QueryString(m => m.OnFields(p => p.PName).Query(searchString))
);
This will work for entire word , like i have to provide search string as
"value"
to search
"value is grater than 100"
only providing val will not work.So how i can fulfill my requirement ?

Your field currently is not_analyzed, You can use edge n-gram analyzer made up of edge ngram filter to token your field before saving the fields on inverted index. You can use the following settings
PUT index_name1323
{
"settings": {
"analysis": {
"analyzer": {
"autocomplete_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"standard",
"lowercase",
"filter_edgengram"
]
}
},
"filter": {
"filter_edgengram": {
"type": "edgeNGram",
"min_gram": 2,
"max_gram": 15
}
}
}
},
"mappings": {
"test_type": {
"properties": {
"props": {
"type": "string",
"analyzer": "autocomplete_analyzer"
}
}
}
}
}
Now you can simply use both query_string or term filter to match both your documents to val
POST index_name1323/_search
{
"query": {
"query_string": {
"default_field": "props",
"query": "val"
}
}
}
Hope this helps

Related

Mongo DB remove nested object

I want to remove a data in the my document. I bolded the id I want to remove
My Code like that but "This code deletes all KeyResultActions with same Id";
var filter = builder.Eq("Id", ObjectId.Parse(objectiveId))
& builder.Eq("KeyResults.Id", ObjectId.Parse(keyResultId))
& builder.Eq("KeyResults.KeyResultActions.Id", ObjectId.Parse(actionId));
var update = Builders<Objective>.Update.PullFilter("KeyResults.$[].KeyResultActions",
Builders<KeyResultAction>.Filter.Eq(x => x.Id, ObjectId.Parse(actionId)));
My document like that;
{
"_id": "**6311d1612559020ef536cb6f**",
"KeyResults": [
{
"_id": "6311d1612559020ef536cb69",
"Title": "Test KeyResult -1 ",
"Description": "Test KeyResult Desc -1",
"KeyResultActions": [
{
"_id": "630f5d4ebb4428127b11fb8e"
},
{
"_id": "630f5d4ebb4428127b11fb8f"
}
]
},
{
"_id": "**6311d1612559020ef536cb6b**",
"Title": "Test KeyResult -2",
"Description": "Test KeyResult Desc -2",
"KeyResultActions": [
{
"_id": "**630f5d4ebb4428127b11fb8e**"
},
{
"_id": "630f5d4ebb4428127b11fb8f"
}
]
}
]
}
You shouldn't use the $[] all positional operator which will remove the first item from the KeyResultActions array for all items in the KeyResults.
Instead, replace it with $ positional operator which selects the first matched element in the array.
MongoDB query
db.collection.update({
"_id": "6311d1612559020ef536cb6f",
"KeyResults._id": "6311d1612559020ef536cb6b",
"KeyResults.KeyResultActions._id": "630f5d4ebb4428127b11fb8e"
},
{
$pull: {
"KeyResults.$[].KeyResultActions": {
_id: "630f5d4ebb4428127b11fb8e"
}
}
})
MongoDB .NET Driver syntax
var update = Builders<Objective>.Update.PullFilter("KeyResults.$.KeyResultActions",
Builders<KeyResultAction>.Filter.Eq(x => x.Id, ObjectId.Parse(actionId)));
Demo

ElasticSearch NEST - FieldValueFactorFunction score function outputting invalid json query

Let me preface this to say I'm newer to ElasticSearch and NEST, and may be doing something wrong. This is using NEST 7.6.2.
I'm following the documentation to create a field_value_factor score function containing a filter and weight using object initializer syntax, i.e.:
new FieldValueFactorFunction
{
Field = "foo",
Modifier = FieldValueFactorModifier.Log1P,
Missing = 1,
Filter = new MatchQuery
{
Field = "bar",
Query = "1"
},
Weight = .2
}
However, at runtime it appears to output an invalid json format in the query itself:
{
"filter": {
"match": {
"bar": {
"query": "1"
}
}
},
"field_value_factor": {
"field": "foo",
"missing": 1.0,
"modifier": "log1p",
"filter": {
"match": {
"bar": {
"query": "1"
}
}
},
"weight": 0.2
},
"weight": 0.2
}
Which fails with the error field_value_factor query does not support [value]. I do know the valid function syntax I'm trying to emulate is the following:
{
"filter": {
"match": {
"bar": {
"query": "1"
}
}
},
"field_value_factor": {
"field": "foo",
"missing": 1.0,
"modifier": "log1p"
},
"weight": 0.2
}
Is this a bug in NEST/Elasticsearch.net? Is my syntax incorrect? Is there an alternate way to do what I'm trying to do?
This was apparently an issue in the version of NEST I was using. Updating the nuget package resolved it.

How to use SelectToken to find value in nested dynamic JSON

I can't figure out how to use JToken to get the "Total Income" amount of "325.00".
I have tried quite a few different lines of code but seem to be missing something obvious.
{
"Rows": {
"Row": [
{
"Rows": {
},
"type": "Section",
"group": "Income",
"Summary": {
"ColData": [
{
"value": "Total Income"
},
{
"value": "325.00"
}
]
}
},
{
}
]
}
}
For the specific JSON sample that you have given in your question, you can extract the 325.00 value using SelectToken like this:
var obj = JObject.Parse(json);
var amount = (string)obj.SelectToken("Rows.Row[0].Summary.ColData[1].value");
Fiddle: https://dotnetfiddle.net/WRMAVu
If you want to extract both the label and the amount you can use SelectTokens instead with a wildcard for the ColData index:
var obj = JObject.Parse(json);
var values = obj.SelectTokens("Rows.Row[0].Summary.ColData[*].value")
.Select(t => (string)t)
.ToArray();
Fiddle: https://dotnetfiddle.net/DHZhS2

ElasticSearch NEST - Find results with special characters

I am trying to write a search query on an elastic index that will return me results from any part of the field value.
I have a Path field that contains values like C:\temp\ab-cd\abc.doc
I want the ability to send a query that will return my any matching part from what I wrote
QueryContainer currentQuery = new QueryStringQuery
{
DefaultField = "Path",
Query = string.Format("*{0}*", "abc"),
};
The above will return results, this will not:
QueryContainer currentQuery = new QueryStringQuery
{
DefaultField = "Path",
Query = string.Format("*{0}*", "ab-cd"),
};
The same goes for any other special character like ##$%^&* and so on.
Is there some generic way to send a query and to find exactly what I searched?
Each of my fields are multi-fields and I can use the *.raw options but do not exactly know how or if I should
Use nGrams to split the text in smaller chunks and use term filter to query it. Pro: it should be faster. Con: the size of the index (disk space) will be larger because more terms (from nGram filter) are generated.
PUT /test
{
"settings": {
"analysis": {
"analyzer": {
"my_ngram_analyzer": {
"tokenizer": "keyword",
"filter": [
"substring"
]
}
},
"filter": {
"substring": {
"type": "nGram",
"min_gram": 1,
"max_gram": 50
}
}
}
},
"mappings": {
"test": {
"properties": {
"Path": {
"type": "string",
"index_analyzer": "my_ngram_analyzer",
"search_analyzer": "keyword"
}
}
}
}
}
And the query:
GET /test/test/_search
{
"query": {
"term": {
"Path": {
"value": "\temp"
}
}
}
}
If you wish, you can use the config above as a sub-field for whatever mapping you already have.
If you want to use query_string there one thing you need to be aware: you need to escape special characters. For example -, \ and : (complete list here). Also, when indexing, the \ char needs escaping, otherwise it will issue an error. This is what I tested especially with query_string: https://gist.github.com/astefan/a52fa4989bf5298102d1

mongodb c# how to work with BSON document

I've spent MANY hours looking for the answer...
This is very easy in PHP but I just can't put it together in C#(I'm new to C# and mongo...)
I'm trying to iterate through all levels of a stored document. The document looks like this:
{
"_id": ObjectId("51f90101853bd88971ecdf27"),
"fields": [
{
"ID": ObjectId("51fd09498b080ee40c00514e"),
"NAME": "ID",
"TYPE": "Text"
},
{
"ID": ObjectId("51fd09a68b080ee40c0064db"),
"NAME": "Title",
"TYPE": "Text"
},
{
"ID": ObjectId("51fd09b28b080ee40c004d31"),
"NAME": "Start Date",
"TYPE": "Date"
},
{
"ID": ObjectId("51fd09c28b080ee40c007f2e"),
"NAME": "Long Description",
"TYPE": "Memo"
}
],
"name": "TODB",
"updated": "Wed Jul 31 2013 08:20:17 GMT-0400 (Eastern Daylight Time)"
}
I have no problem accessing the "name" and "updated" but can't figure out how to access the "fields" array.
Code so far :
{
MongoServer mongo = MongoServer.Create();
mongo.Connect();
var db = mongo.GetDatabase("forms");
mongo.RequestStart(db);
var collection = db.GetCollection("forms");
var query = new QueryDocument("name",
"TODB");
mongo.Disconnect();
}
#foreach(BsonDocument item in collection.Find(query))
{
#item.GetElement("name").Value
#item.GetElement("_id").Value
}
Again, I am able to access the name and _id just not any of the sub document values.
Thanks in advance for any assistance!
After I get the reading figured out, I am also going to want to write data....
There are a few ways, but here's one:
// build some test data
BsonArray dataFields = new BsonArray { new BsonDocument {
{ "ID" , ObjectId.GenerateNewId()}, { "NAME", "ID"}, {"TYPE", "Text"} } };
BsonDocument nested = new BsonDocument {
{ "name", "John Doe" },
{ "fields", dataFields },
{ "address", new BsonDocument {
{ "street", "123 Main St." },
{ "city", "Madison" },
{ "state", "WI" },
{ "zip", 53711}
}
}
};
// grab the address from the document,
// subdocs as a BsonDocument
var address = nested["address"].AsBsonDocument;
Console.WriteLine(address["city"].AsString);
// or, jump straight to the value ...
Console.WriteLine(nested["address"]["city"].AsString);
// loop through the fields array
var allFields = nested["fields"].AsBsonArray ;
foreach (var fields in allFields)
{
// grab a few of the fields:
Console.WriteLine("Name: {0}, Type: {1}",
fields["NAME"].AsString, fields["TYPE"].AsString);
}
You can often use the string indexer ["name-of-property"] to walk through the fields and sub document fields. Then, using the AsXYZ properties to cast the field value to a particular type as shown above.

Categories

Resources