I had troubles joining two DbSets and continued to receive the "cannot be inferred error". I struggled to find a solution so I thought I would share my simple answer. There are several great posts from Jon Skeet and others but most of the answers were over my head.
Here is the code that was causing me trouble:
using(var db = new SomeDataContext())
{
db.DemandData
.Where(demand=> demand.ID == SearchID)
.Join(db.CUST_ORDER_LINE,
supply=> new { supply.LINE, supply.SALES_ORDER_ID },
demand=> new { demand.LINE_NO, demand.CUST_ORDER_ID },
(supply, demand) => new { custOrderLineReturn = demand })
.Select(s => s.custOrderLineReturn )
.ToList();
}
I have done this join so many times that I could not figure out why it would not work until I found a post from Justin Niessner here that says "The names of the properties in the anonymous types (as well as their types) must match exactly." That lead me to this code:
using(var db = new SomeDataContext())
{
return db.DemandData
.Where(demand=> demand.ID == SearchID)
.Join(db.CUST_ORDER_LINE,
supply=> new { LINE_NO = supply.LINE, CUST_ORDER_ID = supply.SALES_ORDER_ID },
demand=> new { demand.LINE_NO, demand.CUST_ORDER_ID },
(supply, demand) => new { custOrderLineReturn = demand })
.Select(s => s.custOrderLineReturn )
.ToList();
}
In the sixth line I added variables LINE_NO = and CUST_ORDER_ID = that matched the field names in line seven.
Related
We've got a pretty basic query we're using to allow users to provide a query text, and then it boosts matches on different fields. Now we want to add another boost based on votes, but not sure where to nest the FunctionScore in.
Our original query is:
var results = await _ElasticClient.SearchAsync<dynamic>(s => s
.Query(q => q
.MultiMatch(mm => mm
.Fields(f => f
.Field("name^5")
.Field("hobbies^2")
)
.Query(queryText)
)
)
);
If I try to nest in FunctionScore around the MultiMatch, it basically ignores the query/fields, and just returns everything in the index:
var results = await _ElasticClient.SearchAsync<dynamic>(s => s
.Query(q => q
.FunctionScore(fs => fs
.Query(q2 => q2
.MultiMatch(mm => mm
.Fields(f => f
.Field("name^5")
.Field("hobbies^2")
)
.Query(queryText)
)
)
)
)
);
My expectation is that since I'm not providing a FunctionScore or any Functions, this should basically do the exact same thing as above. Then, just adding in FunctionScore will provide boosts on the results based on the functions I give it (in my case, boosting based on the votes field just FieldValueFactor).
The documentation around this is a little fuzzy, particularly with certain combinations, like MultiMatch, FunctionScore, and query text. I did find this answer, but it doesn't cover when including query text.
I'm pretty sure it boils down to my still foggy understanding of how Elastic queries work, but I'm just not finding much to cover the (what I would think is a pretty common) scenario of:
A user entering a query
Boosting matches of that query with certain fields
Boosting all results based on the value of a numeric field
Your function_score query is correct, but the reason that you are not seeing the results that you expect is because of a feature in NEST called conditionless queries. In the case of a function_score query, it is considered conditionless when there are no functions, omitting the query from the serialized form sent in the request.
The easiest way to see this is with a small example
private static void Main()
{
var defaultIndex = "my-index";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool, new InMemoryConnection())
.DefaultIndex(defaultIndex)
.DisableDirectStreaming()
.PrettyJson()
.OnRequestCompleted(callDetails =>
{
if (callDetails.RequestBodyInBytes != null)
{
Console.WriteLine(
$"{callDetails.HttpMethod} {callDetails.Uri} \n" +
$"{Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)}");
}
else
{
Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
}
Console.WriteLine();
if (callDetails.ResponseBodyInBytes != null)
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" +
$"{new string('-', 30)}\n");
}
else
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{new string('-', 30)}\n");
}
});
var client = new ElasticClient(settings);
var queryText = "query text";
var results = client.Search<dynamic>(s => s
.Query(q => q
.FunctionScore(fs => fs
.Query(q2 => q2
.MultiMatch(mm => mm
.Fields(f => f
.Field("name^5")
.Field("hobbies^2")
)
.Query(queryText)
)
)
)
)
);
}
which emits the following request
POST http://localhost:9200/my-index/object/_search?pretty=true&typed_keys=true
{}
You can disable the conditionless feature by marking a query as Verbatim
var results = client.Search<dynamic>(s => s
.Query(q => q
.FunctionScore(fs => fs
.Verbatim() // <-- send the query *exactly as is*
.Query(q2 => q2
.MultiMatch(mm => mm
.Fields(f => f
.Field("name^5")
.Field("hobbies^2")
)
.Query(queryText)
)
)
)
)
);
This now sends the query
POST http://localhost:9200/my-index/object/_search?pretty=true&typed_keys=true
{
"query": {
"function_score": {
"query": {
"multi_match": {
"query": "query text",
"fields": [
"name^5",
"hobbies^2"
]
}
}
}
}
}
I have a json document like following with sub-document
[
{
"id": "73e799df-b7a5-7470-4f25-ee6c1811a5b2",
"tblType": "search",
"memberId": 2,
"results": [
{"prcnt": 89,"distance": 8867775.747141607},
{"prcnt": 30,"distance": 11010216.470879028},
{"prcnt": 96,"distance": 9128590.716183286},
{"prcnt": 41,"distance": 9652043.937920697}
]
}
]
i want to get the 'results' tag data only in the query with order by prcnt
SELECT top 10 m.results FROM m join r in m.results where m.memberId=2
and m.tblType='search' order by r.prcnt
when i am executing the query, getting the error as follows..
Order-by over correlated collections is not supported.
how to get the data per my requirement.
Thanks in advance!!
According to your requirement, I have checked this issue. Here are my understanding about this issue:
If the memberId and tblType could locate the single document, then you could refer to this similar issue:
UDF
function sortByPrcntNumber (results) {
return results.sort(function(a,b){
return a.prcnt-b.prcnt;
});
}
QUERY
SELECT value udf.sortByPrcntNumber(c.results)
from c
where c.memberId=2 and c.tblType='search'
If the memberId and tblType could retrieve multiple documents, I assumed that you could leverage STORED PROCEDURES as follows:
function sample(top,tblType,memberId){
var collection=getContext().getCollection();
var isAccepted=collection.queryDocuments(
collection.getSelfLink(),
"SELECT value {\"prcnt\":r.prcnt,\"distance\":r.distance} from c join r in c.results where c.tblType='"+tblType+"' and c.memberId="+memberId+"",
function(err,feed,options){
if(err) throw err;
if(!feed||!feed.length) getContext().getResponse().setBody("no docs found");
else {
//order by prcnt
var orderedFeed=feed.sort(function(a,b){
return a.prcnt-b.prcnt;
});
//select top
var topFeed=orderedFeed.slice(0,top);
getContext().getResponse().setBody(topFeed);
}
});
if(!isAccepted) throw new Error("The query was not accepted by the server.");
}
Result
I have some quite simple .NET logic that I'm transplanting into a Scala codebase, and I don't really know the first thing about Scala. It includes a LINQ query that groups a collection of tagged objects by making use of an anonymous type projection to flatten and join, followed by grouping, eg:
var q = things.SelectMany(t => t.Tags, (t, tag) => new { Thing = t, Tag = tag })
.GroupBy(x => x.Tag, x => x.Thing);
In Scala it looks like flatMap might be of use, but I can't figure out how to combine it with groupBy via an anonymous.
Is this kind of thing a lot more complicated in Scala, or am I missing something simple?
UPDATE:
I ended up going with:
things.flatMap(t => t.Tags.map(x => (x,t))).groupBy(x => x._1)
and then of course later on when I access a value in the map I need to do:
.map(x => x._2)
to get the groups out of the tuple.
Simple when you know how!
Seems to me you want to do something like.
case class Tag(tag:String)
case class Thing(Tags : Seq[Tag])
val things :Seq[Thing] = Seq(Thing(Seq(Tag(""))))
val q = things.map {
thing => new {
val Thing = thing
val Tags = thing.Tags
}
}.flatMap {
thingAndTags => thingAndTags.Tags.map {
tag => new {
val Thing = thingAndTags.Thing
val Tag = tag
}
}
}. groupBy {
thingAndTag => thingAndTag.Tag
}.map {
tagAndSeqOfThingAndTags =>
tagAndSeqOfThingAndTags._1 -> tagAndSeqOfThingAndTags._2.map(x => x.Thing)
}
But in Scala anonymous objects are not really common but you can use Tuple2[T1,T2] instead of all the new { val ...}s,
val q = things.map {
thing => ( thing->thing.Tags)
}.flatMap {
thingAndTags => thingAndTags._2.map {
tag => (thingAndTags._1, tag)
}
}.groupBy {
thingAndTag => thingAndTag._2
}.map {
tagAndSeqOfThingAndTags =>
tagAndSeqOfThingAndTags._1 -> tagAndSeqOfThingAndTags._2.map(x => x._1)
}
its just a little confusing with all the ._1s and ._2s
Lets say I have a "category" table, each category has associated data in the "data" table and it has associated data in other tables "associated" and I want to remove a category with all it's associated data.
What I'm currently doing is something like this:
getAllDataIdsFromCategory()
.then(removeAllAssociated)
.then(handleChanges)
.then(removeDatas)
.then(handleChanges)
.then(removeCategory)
.then(handleChanges);
Is there a way to chain these queries on the db-side?
my functions currently look like this:
var getAllDataIdsFromCategory = () => {
return r
.table('data')
.getAll(categoryId, { index: 'categoryId' })
.pluck('id').map(r.row('id')).run();
}
var removeAllAssociated = (_dataIds: string[]) => {
dataIds = _dataIds;
return r
.table('associated')
.getAll(dataIds, { index: 'dataId' })
.delete()
.run()
}
var removeDatas = () => {
return r
.table('data')
.getAll(dataIds)
.delete()
.run()
}
notice that I cannot use r.expr() or r.do() since I want to do queries based on the result of the previous query.
The problem with my approach is that it won't work for large amounts of "data" since I have to bring all of the ids to the client side, and doing paging for it in the client side in a loop seems like a workaround.
You can use forEach for this:
r.table('data').getAll(categoryID, {index: 'categoryId'})('id').forEach(function(id) {
return r.table('associated').getAll(id, {index: 'dataId'}).delete().merge(
r.table('data').get(id).delete())
});
Firstly, sorry if this is already answered, but I couldn't find it.
I'm having some trouble retrieving all attributes from a Parse response.
I found this select() method on the documentation, which would do exactly what I need, pointing out which columns should be returned, but it seem to
take no effect.
The bit of code
var answersQuery = new Parse.Query("answer");
answersQuery.select(["objectId", "description", "category_id", "sale_id", "image_url"]);
answersQuery.equalTo("previous_question_id", {
__type: "Pointer",
className: "question",
objectId: questionId
});
answersQuery.find().then(function(answersData) {
if (typeof(answersData) != "undefined") {
var answers = [];
for (var i in answersData) {
answers.push({
id : answersData[i].id,
sale_id : answersData[i].get("sale_id"),
image_url : answersData[i].get("image_url"),
category_id: answersData[i].get("category_id"),
description: answersData[i].get("description")
});
}
response.success({
answers : answers
});
} else {
response.error("answers not found");
}
});
But the return I get always contains just the "id" and the "description" attributes
{"result":{"answers":[{"description":"COMPRAS","id":"x3pS8sadDS"},{"description":"CINEMA","id":"MVHwJqifzE"}]}}
If I change the "id" to something like "asdf" it will reflect in the response, so I'm sure I'm dealing iwth the same object I can see in the response.
Any ideas would be much appreciated.
Does the answers table has too many fields? Have you tried not specifying fields (I mean, to using the select statement)?