Given a hash map keyed by unique key M that contains objects with unique ids N (numeric for simplicity):
{
// [key: M]: [{ id: N }],
a3b84ea: [{ id: 10129 }, { id: 32241 }],
f4b00dd: [{ id: 57909 }, { id: 82033 }],
b9982ca: [{ id: 20348 }, { id: 97412 }],
}
I would like to be able to efficiently look up a value by ANY of the ids N.
e.g.
get(10129) → [{ id: 10129 }, { id: 32241 }]
get(32241) → [{ id: 10129 }, { id: 32241 }]
get(57909) → [{ id: 57909 }, { id: 82033 }]
...
I'm pretty sure that a O(1) bitwise OR hashing function is not possible, as there is no way to get the compound hash of, for example, 10129 and 32241 when you only have 10129.
However, is there a data structure that would allow O(2) lookup with any of the ids N? i.e. a 2-step lookup without having to iterate through all keys M?
Related
We are using elastic search 5 (yes I know it is EOL but it is what it is)
Elastic newbie here with a rather complicated task:
Let's imagine we have an event index filled with multiple event documents. Those event documents might have n speakers attached in a speakers object array. A speaker has a gender attribute.
How can I achieve the following query?
"return event for each speaker whose gender is x "
returning query result:
{
page: 1,
pageSize: 20,
total: 3
items: [
{
id: 1,
speakers: [
{
name: 'Sascha',
gender: 'x'
}
]
},
{
id: 1,
speakers: [
{
name: 'Leo',
gender: 'x'
}
]
},
{
id: 2,
speakers: [
{
name: 'Rue',
gender: 'x'
}
]
},
]
}
event index filled with three event documents
event 1
{
id: 1,
speakers: [
{
name: 'Sascha',
gender: 'x'
},
{
name: 'Leo',
gender: 'x'
},
]
}
event 2
{
id: 2,
speakers: [
{
name: 'Thomas',
gender: 'm'
},
{
name: 'Rue',
gender: 'x'
},
]
}
event 3
{
id: 2,
speakers: [
{
name: 'Nicole',
gender: 'f'
}
]
}
I didn't even start to code or write a query because I am not sure if elastic is built to give me a result like the one I want to achieve.
I don't even know how to articulate the type of query I am trying to achieve :/
Or do I have to create a new index which combines event and speaker index in a way I can work with?
I'm trying to use nativescript-couchbase-plugin.
Here is my code:
whereArray.push({ property: "type_id", comparison: "equalTo", value: typeId });
return itemsDb.query({
select: [],
where: whereArray,
order: [{property: "rating", direction: "desc"}],
limit: this.PAGE_SIZE,
offset: page * this.PAGE_SIZE
});
Everything works fine: condition in where clause, ordering, limit and offset.
But I want to add something new to my condition and I'm trying to do this:
whereArray.push({ property: "title", comparison: "like", value: "some name"});
or
whereArray.push({ property: "filters", comparison: "in", value: [1,2,3]});
And these cases don't work. Neither of them. The only one that works is the first one with type_id
So the question is - how to use where array to query corresponding data?
Data Sample:
{
"type_id": 2,
"title": "some name",
"regionId": 372,
"uid": 16177,
"filters": [
1,
2,
3
]
},
P.S. There is an issue inside original repository. But it has no activity at all.
I must agree the plugin documentation could be better. But if you go through the TypeScript declaration, you will find the issue with your code.
When you are adding multiple where conditions, you must include a logical operator.
import {
Couchbase,
QueryLogicalOperator,
QueryComparisonOperator
} from "nativescript-couchbase-plugin";
const database = new Couchbase("my-database");
// Insert docs for testing
const documentId = database.createDocument({
type_id: 2,
title: "some name",
regionId: 372,
uid: 16177,
filters: [1, 2, 3]
});
console.log(documentId);
// Query
const results = database.query({
select: [],
where: [
{
property: "type_id",
comparison: "equalTo",
value: 2,
logical: QueryLogicalOperator.AND
},
{
property: "filters",
comparison: "in",
value: [1, 2, 3]
}
],
order: [{ property: "rating", direction: "desc" }],
limit: 10
});
console.log(results);
Taking a look at different examples on the documentation, I found that the only way to include multiple graphs (or lines) on a serial chart would be to do so by placing the data in one array as such:
[{
category: 1,
value1: .8,
value2: .64,
},
{
category: 2,
value1: .75,
value2: -.4,
}];
However, this is rather tedious if you have multiple data sets you are trying to display at once; is there an alternative way to do this, where you would pass multiple arrays at once (this is what I figured an implementation would look like, but it is not the case):
[
// First set of data
{ category: 0, value: .5},
{ category: 1, value: .5},
{ category: 2, value: .5},
{ category: 3, value: .5},
{ category: 4, value: .3},
{ category: 5, value: 1}
],
// Second set of data
[
{ category: 0, value: .5 },
{ category: 1, value: .3 },
{ category: 2, value: .25 },
{ category: 3, value: .6 },
{ category: 4, value: .79 },
{ category: 5, value: .81 }
]],
Any ideas on how this may be done? Or would I need to do switch to a different type of chart?
This isn't possible in the regular AmCharts JavaScript Charts library. The only supported format is a single array of objects with the values consolidated by category as you've noticed. You'll have to preprocess your data beforehand.
The AmCharts Stock Chart library supports separate arrays of data in the dataSets array, however it only supports date-based data.
AmCharts.makeChart("chartdiv", {
"type": "stock",
"dataSets": [{
// other properties omitted
"dataProvider": [{
category: "2017-08-01,
value: 3
}, {
category: "2017-08-02,
value: 2
}, {
category: "2017-08-03,
value: 1
}, // ...
]
}, {
// other properties omitted
"dataProvider": [{
category: "2017-08-01,
value: 10
}, {
category: "2017-08-02,
value: 9
}, {
category: "2017-08-03,
value: 5
}, // ...
]
},
// ...
]
// ...
});
You can see this in action in the any of the stock chart demos.
Is it possible to persist grid sort/filter/selection on grid.refresh() in some smart optimized way? I need to refresh grid on window resize event to adjust to a new window size. I guess refresh internally destroys and recreates grid, not accounting for possible active sort/filter/selection. Because grid can contain a lot of data (virtual scrolling), I would like to a avoid unnecessary db querying, rendering and sorting. I guess I am looking for a refresh which will refresh on existing data.
Seams like they just implemented it - here is the example.
Maybe to be included in the next release.
Here is the code in the example that does this:
jQuery(function ($) {
$("#grid").shieldGrid({
dataSource: {
data: gridData,
schema: {
fields: {
id: { type: Number },
name: { type: String },
company: { type: String },
phone: { type: String },
age: { type: Number },
gender: { type: String }
}
},
filter: {
// create the initial filter in that form
and: [
{ path: "name", filter: "con", value: "John" }
]
}
},
filtering: {
enabled: true
},
paging: true,
columns: [
{ field: "id", width: "250px", title: "ID" },
{ field: "name", title: "Person Name", width: "250px" },
{ field: "company", title: "Company" },
{ field: "phone", title: "Phone", width: "250px" },
{ field: "age", title: "Age" }
]
});
});
I found the solution in refresh method it self. It accepts options objects where one can provide current data source options to persist. Example to persist sort and/or filter:
var options = {
dataSource: $("#grid").swidget().dataSource
}
$("#grid").swidget().refresh(options);
Please stand me correct if I am wrong here. For selections I guess one can retrieve selected indices and reselect after calling refresh.
EDIT: filter and sort are preserved, but filter row resets (loses all active input values). Could this be a bug? How to keep values in filter row?
What I'm trying to accomplish is to apply an "automatic" secondary column sort when a user sorts a column in a kendo grid.
So in this JS fiddle example, if a user sorts by "Value", it'll also sort by "Name". Note that the 0s are sorted together, but the names aren't alphabetical. I'd like them to be alphabetical (the secondary sort).
Here's an attempt at overriding the datasource sorting to accomplish this. I'm taking the user's original sort and the adding an additional sort on "SortedName". Based on the sorting array that's logged, it seems to be close but is still not working.
Any other ideas on how to accomplish this?
Note: I don't want to allow users to sort by multiple columns. The real world example I'm using this for can have up to 50+ columns (unfortunately), so multiple sort can get confusing / unintuitive. And I'd like it to be done behind the scenes without extra user interaction.
Example code for overriding kendo datasource sort():
dataSource.originalSort = dataSource.sort;
dataSource.sort = function () {
// take the user's sort and apply sorting on an additional column
// the sort array should look like this:
[
{ field: "Value", dir: "asc" }, // this is what the user sorted by
{ field: "SortedName", dir: "asc" }, // and I'm adding this
]
return dataSource.originalSort.apply(this, arguments);
}
Please try with the below code snippet.
<div id="grid">
</div>
<script>
var dataSource = new kendo.data.DataSource({
data: [
{ Name: "Lisa", Value: 1 },
{ Name: "Dan", Value: 12 },
{ Name: "Ken", Value: 5 },
{ Name: "Arthur", Value: 15 },
{ Name: "Bob", Value: 0 },
{ Name: "Sally", Value: 0 },
{ Name: "Alexis", Value: 0 },
{ Name: "Cody", Value: 0 },
{ Name: "Steve", Value: 0 },
{ Name: "Andrew", Value: 0 },
{ Name: "Duke", Value: 0 }
],
schema: {
model: {
fields: {
Name: { type: "string" },
Value: { type: "number" }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
dataBound: function (e) {
var isSortedByName = false;
var grid = $("#grid").data("kendoGrid");
var ds = grid.dataSource;
var sort = ds.sort();
if (sort) {
for (var i = 0; i < sort.length; i++) {
if (sort[i].field == "Name") {
isSortedByName = true;
}
}
if (isSortedByName == false) {
sort.push({ field: "Name", dir: "asc" });
ds.sort(sort);
}
}
},
columns: [
{ field: "Name" },
{ field: "Value" }
],
sortable: true
});
</script>