When I add the index below to my raven database a simple query like
return Session.Query<R>().FirstOrDefault(x => x.RId == Id);
Always returns null. Only after forcing Raven to remove my custom index does desired functionality return. Why is this?
The Index with side effects:
public class RByLatestCommentIndex : AbstractIndexCreationTask<R>
{
public RByLatestCommentIndex()
{
SetMap();
}
void SetMap()
{
Map = r => r.Select(x => new
{
Id = x.Id,
TimeStamp = x.Comments.Count() > 0 ? x.Comments.Max(u => u.Created)
: x.Created
}).OrderByDescending(y => y.TimeStamp).Select(r => new { Id = r.Id });
}
}
public class RIdTransformer : AbstractTransformerCreationTask<R>
{
public RIdTransformer()
{
TransformResults = ids => ids.Select(x => LoadDocument<R>(x.Id));
}
}
EDIT:
In response to Ayende Rahien's comment:
There's a query in the DB which would otherwise be used (Auto/R/ByRID) but the index used looks like this, puzzling enough:
from doc in docs.Rs select new { Images_Count__ = doc.Images["Count()"], RId = doc.RId }
What explains this behaviour? And, will I have to add a static index to be able to query R by RId ?
Related
I'm trying to create a static index where I want all documents where a key exists and has a value. The value itself is not important, only the key exists.
I'm exploring this example with dynamic fields:
https://ravendb.net/docs/article-page/2.5/csharp/client-api/advanced/dynamic-fields
... and although I'm getting the index to work, I'm not sure if the query I'm using is correct.
This is the sample class:
public class Result
{
public Dictionary<string, List<Data>> Results { get; set; }
}
The key in the dictionary is the ID of a user (for example "user/1") and the value is a list of data-objects. The so the json-structure looks like this:
{
"Results" :
{
"user/1": [{...}],
"user/2": [{...}],
}
}
The index I use is this:
public class Result_ByUserId : AbstractIndexCreationTask<Result>
{
public Result_ByUserId()
{
Map = res => from r in res
select new
{
_ = r.Results
.Select(d => CreateField(d.Key, d.Value))
};
}
}
My problem comes down to the query, as it assumes I want to look at a specific key and value.
var resultat = session.Advanced.DocumentQuery<Result>("Result/ByUserId ")
.WhereEquals("user/1", "") // How do I write a !isNullOrEmpty?
.ToList();
... which I don't want to do. I only want the results that has a key in which the value is not null or empty. Does anybody have any good tips?
What you can do is index a boolean flag depending on if the dictionary has a value or not and then query on that.
public class Result_ByUserId : AbstractIndexCreationTask<Result>
{
public Result_ByUserId()
{
Map = res => from r in res
select new
{
_ = r.Results
.Select(d => CreateField(d.Key, d.Value != null ? true : false, false, true))
};
}
}
The query can then be:
var resultat = session.Advanced.DocumentQuery<Result>("Result/ByUserId ")
.WhereEquals("user/1", true)
.ToList();
This will return any Result documents that has a Dictionary with a key of user/1 and a dictionary value that's not null.
Not sure it's the best way of doing it, but it worked for me...
Hope this helps!
Here is index class
public class Facility_SearchTerm : AbstractIndexCreationTask<FacilityApplication>
{
public Facility_SearchTerm()
{
Map = facilities => from facility in facilities
select new
{
facility.FacilityName
};
Indexes.Add(x => x.FacilityName, FieldIndexing.Analyzed);
}
}
And here is a simple query
var query = session.Advanced.DocumentQuery<FacilityApplication, Facility_SearchTerm>()
.Statistics(out statsRef)
.Search(s => s.FacilityName, "abc")
.Skip(size * (page - 1))
.Take(size);
What is wrong? I got the error
"Query failed. See inner exception for details. at Raven.Client.Connection.ServerClient.Query(String index, IndexQuery query, String[] includes, Boolean metadataOnly, Boolean indexEntriesOnly)
I want to use MinHash elastic search plugin in NEST Elasticsearch.net.
How can I use minhash plugin in nest?
Create index with following mapping:
elasticClient.CreateIndex(descriptor => descriptor
.Index("my_index")
.Analysis(
analysis => analysis.Analyzers(bases => bases.Add("minhash_analyzer", new CustomAnalyzer
{
Tokenizer = "standard",
Filter = new[] {"minhash"}
})))
.AddMapping<IndexElement>(
mappingDescriptor =>
mappingDescriptor
.Properties(p => p
.String(s => s.Name(element => element.Message).CopyTo("minhashvalue"))
.Custom(new MiniHashMapping()))));
class MiniHashMapping : BinaryMapping
{
[JsonProperty("minhash_analyzer")]
public string Analyzer { get { return "minhash_analyzer"; } }
public MiniHashMapping()
{
Type = "minhash";
Name = "minhashvalue";
}
}
class IndexElement
{
public string Message { get; set; }
}
Index sample document:
elasticClient.Index(new IndexElement
{
Message = "Fess is Java based full text search server provided as OSS product."
}, descriptor => descriptor.Index("my_index"));
Tell elasticsearch to include fields in response:
var searchResponse = elasticClient.Search<IndexElement>(s => s.Query(q => q.MatchAll()).Fields("*"));
You can get hash value from searchResponse.Hits[..].Fields or searchResponse.FieldSelections.
Hope this helps.
So far I have an index like this:
public class Animals_Search : AbstractMultiMapIndexCreationTask<Animals_Search.Result> {
public class Result {
public object[] Content { get; set; }
}
public Animals_Search() {
AddMap<Dog>(a => from b in a select new Result { Content = new object[] { b.Name, b.Breed} });
AddMap<Cat>(a=> from bin docs select new Result { Content = new object[] { b.Name, b.Breed} });
Index(x => x.Content, FieldIndexing.Analyzed);
}
}
And a query like this:
session.Query<Animals_Search.Result, Animals_Search>()
.Search(a => a.Content, match)
.As<Animal>()
.ToList();
This works if I provide search terms like "Collie" or "Terrier", but not "Coll" or "Terr"
How do I rewrite the query to work something like String.Contains("Terr")?
RavenDB make it hard to do contains query, because for the most part, they aren't needed.
What you probably want is to do a StartsWith, instead.
session.Query<Animals_Search.Result, Animals_Search>()
.Where(a => a.Content.StartsWith(match))
.As<Animal>()
.ToList();
Based on this article from Ayende i have created the following index definition
public class ProductsSearch : AbstractIndexCreationTask<Product, ProductsSearch.Result>
{
public class Result
{
public string Query { get; set; }
}
public ProductsSearch()
{
Map = products => from product in products
select new
{
Query = new object[]
{
product.Title,
product.Tags.Select(tag => tag.Name),
product.Tags.SelectMany(tag => tag.Aliases, (tag, alias) => alias.Name)
}
};
Index(x => x.Query, FieldIndexing.Analyzed);
}
}
One difference is that i must use a SelectMany statement to get the aliases of a tag.
A tag can have many aliases (i. e. tag: mouse alias:pointing device)
I have no idea why the SelectMany line breaks the index. If i remove it, the index works.
This should work:
Map = products => from product in products
from tag in product.Tags
from alias in tag.Aliases
select new
{
Query = new object[]
{
product.Title,
tag.Name,
alias.Name
}
};