I have config file that inherits a list of properties from a parent file. Parent file looks like below
object: {
x : {
.....
name: x
}
y : {
.....
name: y
}
}
And my config file is as below
include "parent.conf"
childConfig : {
x : ${parent.object.x}
y : ${parent.object.y}
}
I want to iterate over all the members of childConfig and change the name to 'newName' for each. One way would be
include "parent.conf"
childConfig : {
x : ${parent.object.x}
y : ${parent.object.y}
x.name: "newName"
y.name: "newName"
}
But this is cumbersome if the list grows large. Is there a way to iterate over the configs (maybe for-each?)to set 'name' field for each member?
Related
I have following data in cosmosDb
[
{
accountId : "12453"
tag : "abc"
},
{
accountId : "12453"
tag : "bcd"
},
{
accountId : "34567"
tag : "qwe"
},
{
accountId : "34567"
tag : "xcx"
}
]
And desired output is something like this
[
{
accountId : "123453"
tag : {
"abc",
"bcd"
},
{
accountId : "34567"
tag : {
"qwe",
"xcx"
}
]
I tried Join, array and group by in multiple ways but didn't work.
Below query gives similar output but rather than count I am looking for an array of tags
select c.accountId, count(c.tag) from c where c.accountId = "12453" group BY c.accountId
Also tried below query
select c.accountId, ARRAY(select c.tag from c IN f where f.accountId = "12453") as tags FROM f
This doesn't return any tag values and I get below output but I need distinct accountId and when I try DISTINCT on accountId, it gives an error.
[
{
accountId : "12,
tag : []
}
........
]
Can someone please help with correct query syntax
As M0 B said, this is not supported. Cosmos DB can't combine arrays across documents. You need to handle this on your client side.
I'm looking for a query which can find all of the nodes which have properties that match a parameter which is an object. The properties of the node can be a superset (contain more properties than the filter)
e.g.
:param obj : { first : "first" }
CREATE (n:Test { first : "first", second : "second" });
CREATE (m:Test { first : "first" });
CREATE (f:Fail { first : "bad", second : "second" });
MATCH (c)
WHERE
PROPERTIES(c) = $obj
RETURN c;
n and m should be returned as they are matching on first : "first"
it is doable with apoc, basically by matching the obj with a submap of the properties, containing only the keys that are also present in obj
WITH { first : "first" } AS obj
MATCH (c)
WHERE apoc.map.submap(properties(c),keys(obj),[],false)= obj
RETURN c
I want to search from my domain class with ElasticSearch, but it's a nested query and the match, that I want, is three levels deep.
Only the domain class that I'm searching from is set as root, all others are set as components and not root for searchable configuration.
When I do the search it gives me matches, but the count is wrong and there are totally wrong matches inside there.
I should get 4000 matches, but I get 20000 matches and I have no clue why it doesn't work as expected.
When I started fiddling around, I changed the mappings between my domain classes and it then gave me correct matches, but the thing is that I do not want to do this kind of changes in my prod environment.
I'm going to give two examples. The first one shows my domain classes' relations currently (the one that doesn't work) and the other one is with the change, that made the search work correctly.
Not correctly working example
class A {
String id
String name
B b
static searchable = {
b component: true
}
}
class B {
String id
String name
C c
static searchable = {
root false
c component: true
}
}
class C {
String id
String name
static belongsTo = [d: D]
static searchable = {
root false
d component: true
}
}
class D {
String id
String name
static searchable = {
root false
}
}
Correctly working example
class A {
String id
String name
B b
static searchable = {
b component: true
}
}
class B {
String id
String name
C c
static searchable = {
root false
c component: true
}
}
class C {
String id
String name
D d
static searchable = {
root false
d component: true
}
}
class D {
String id
String name
static searchable = {
root false
}
}
As you can see the only difference in relations is that in the first example class D belongs to class C and in the second example class D is just a field in class C. In the database D is referenced in C exactly the same in both cases.
The search closure that I created looks like:
bool {
must {
nested {
path = "b"
query {
nested {
path = "b.c"
query {
path = "b.c.d"
query {
bool {
must {
match("b.c.d.id": "142342342342")
}
}
}
}
}
}
}
}
}
Do I really have to change my relations for the domain classes to make the search work or am I just doing the search wrong?
What could cause the issue in general?
EDIT
ElasticSearch mapping for the field "d" inside "c", is exactly the same in both cases:
"c":{
"type":"nested",
"properties":{
"class":{
"type":"string"
},
"dateCreated":{
"type":"date",
"format":"strict_date_optional_time||epoch_millis",
"include_in_all":true
},
"d":{
"type":"nested",
"properties":{
"class":{
"type":"string"
},
"id":{
"type":"string"
},
"name":{
"type":"string",
"term_vector":"with_positions_offsets",
"include_in_all":true
}
}
}
EDIT 2
So it seems that the problem was not rooted in the mappings, but rather that when doing a search with at least three levels of nested objects, then ElasticSearch wasn't able to correctly find the matches with the word match. I got it working with match_phrase.
So important lesson, when searching through for example ids and you your query has multi level nesting and you want an exact match, then one should use match_phrase!
I suggest to use match_phrase over match.
match_phrase query will analyze the input if analyzers are defined for the queried field and find documents matching the following criteria :
all the terms must appear in the field
they must have the same order as the input value
Given a namedQuery:
class MyDomainObject {
String someProperty
static namedQueries = {
myNamedQuery {
// some implementation here
}
}
}
I can use it to generate a list, sorted by a single key, like this (documentation for 2.4.3 here):
def resultsList = MyDomainObject.myNamedQuery.list(sort: "someProperty", order: "desc")
How do I order the results by multiple columns? I'd like to be able to define the sort parameters dynamically, not define them in the query.
I'm sure there's a better way, but I ended up creating another named query that I can concatenate onto my chosen one (I could always incorporate into the original query too).
// expects to be passed a List containing a series of Maps
orderByMultipleColumns { List columnsToSortBy ->
columnsToSortBy.each { Map field ->
order("${field.fieldName}", field.fieldOrder)
}
}
// usage:
List orderByList = []
// ...
// within some loop that I use:
orderByList << [fieldName: someValue, fieldOrder: dir] // dir == 'asc' or 'desc'
// ...
MyDomainObject.myNamedQuery().orderByMultipleColumns(orderList).listDistinct(max: length, offset: start)
I have a document that has an array:
{
_id: ObjectId("515e10784903724d72000003"),
association_chain: [
{
name: "Product",
id: ObjectId("4e1e2cdd9a86652647000003")
}
],
//...
}
I'm trying to search the collection for documents where the name of the first item in the association_chain array matches a given value.
How can I do this using Mongoid? Or if you only know how this can be done using MongoDB, if you post an example, then I could probably figure out how to do it with Mongoid.
Use the positional operator. You can query the first element of an array with .0 (and the second with .1, etc).
> db.items.insert({association_chain: [{name: 'foo'}, {name: 'bar'}]})
> db.items.find({"association_chain.0.name": "foo"})
{ "_id" : ObjectId("516348865862b60b7b85d962"), "association_chain" : [ { "name" : "foo" }, { "name" : "bar" } ] }
You can see that the positional operator is in effect since searching for foo in the second element doesn't return a hit...
> db.items.find({"association_chain.1.name": "foo"})
>
...but searching for bar does.
> db.items.find({"association_chain.1.name": "bar"})
{ "_id" : ObjectId("516348865862b60b7b85d962"), "association_chain" : [ { "name" : "foo" }, { "name" : "bar" } ] }
You can even index this specific field without indexing all the names of all the association chain documents:
> db.items.ensureIndex({"association_chain.0.name": 1})
> db.items.find({"association_chain.0.name": "foo"}).explain()
{
"cursor" : "BtreeCursor association_chain.0.name_1",
"nscanned" : 1,
...
}
> db.items.find({"association_chain.1.name": "foo"}).explain()
{
"cursor" : "BasicCursor",
"nscanned" : 3,
...
}
Two ways to do this:
1) if you already know that you're only interested in the first product name appearing in "association_chain", then this is better:
db.items.find("association_chain.0.name":"something")
Please note that this does not return all items, which mention the desired product, but only those which mention it in the first position of the 'association_chain' array.
If you want to do this, then you'll need an index:
db.items.ensureIndex({"association_chain.0.name":1},{background:1})
2) if you are looking for a specific product, but you are not sure in which position of the association_chain it appears, then do this:
With the MongoDB shell you can access any hash key inside a nested structure with the '.' dot operator! Please note that this is independent of how deeply that key is nested in the record (isn't that cool?)
You can do a find on an embedded array of hashes like this:
db.items.find("association_chain.name":"something")
This returns all records in the collection which contain the desired product mentioned anywhere in the association_array.
If you want to do this, you should make sure that you have an index:
db.items.ensureIndex({"association_chain.name":1},{background: 1})
See "Dot Notation" on this page: http://docs.mongodb.org/manual/core/document/
You can do this with the aggregation framework. In the mongo shell run a query that unwinds the documents so you have a document per array element (with duplicated data in the other fields), then group by id and any other field you want to include, plus the array with the operator $first. Then just include the $match operator to filter by name or mongoid.
Here's the query to match by the first product name:
db.foo.aggregate([
{ $unwind:"$association_chain"
},
{
$group : {
"_id" : {
"_id" : "$_id",
"other" : "$other"
},
"association_chain" : {
$first : "$association_chain"
}
}
},
{ $match:{ "association_chain.name":"Product"}
}
])
Here's how to query for the first product by mongoid:
db.foo.aggregate([
{ $unwind:"$association_chain"
},
{
$group : {
"_id" : {
"_id" : "$_id",
"other" : "$other"
},
"association_chain" : {
$first : "$association_chain"
}
}
},
{ $match:{ "association_chain.id":ObjectId("4e1e2cdd9a86652647000007")}
}
])