Ordered search results in Mongodb? - search

Am doing a simple tag search using mongodb with data being stored in a list.
Entity A {_id:...,tags : ['a','b','f']}
Entity B {_id:...,tags : ['g','a','v']}
Entity C {_id:...,tags : ['a','c','e']}
Entity D {_id:...,tags : ['c','s','e']}
Entity E {_id:...,tags : ['a','c','s']}
Search String : 'a c s g'
Query being
db.collecction.find({tags:{$in:['a','c','s','g']}})
Expected Response would be Entity with most matching tags at top and rest thereafter.
Reponse:
1.Entity E - 3 tags matched
2.Entity D/C/B - 2 tags matched
3.Entity C/B/D - 2 tags matched
4.Entity B/D/C - 2 tags matched
5.Entity A - 1 tag matched
What would be the best way to achieve the same??

You have to implement the ranking/sorting on the application level.
There is nothing in MongoDB that would help you here.
You may look into
http://www.mongodb.org/display/DOCS/Aggregation
but I don't see how this could be used for your particular usecase.

Related

Manipulating value from complex query in Neo4j

I am new to Neo4j DB and I have a Neo4j DB with the following nodes,
Attribute
Entity1
Entity2 - has relation with children as label CHILD
Entity2-1
Entity2-2
...
Entity2-n
And all entities may have relation with others which has label VALUE and property value.
Relationships:
Entity2 -> Attribute
Entity2-n -> Attribute
Entity2 -> Entity1
Entity2-n -> Entity1
Entity1 -> Attribute
I need to fetch these node's relation values and if entity has no direct value then need to fetch it's parent entity value.
For example, if entity2-2has no relation with Attribute, then need to check if it's parent entity2 has relation with value, if not get the Attribute node value.
For this, I am trying this query, but not working as expected and getting empty values
MATCH (a:ATTRIBUTE {name: 'test' })
match (e1:ENTITY1 {id:'c0f333ca-a9cc-4c09-ac30-7c460512f1f9' })
optional match ((e1)-[entity1GlobalValue:VALUE {id:a.id}]->(a))
optional match ((e2:ENTITY2 {id: 'c47004cc-3f48-51fd-9a38-69274341e344'})-[:CHILD]->(e2Children:ENTITY2))
optional match ((e2Children)<-[:CHILD*]-(e2Parent:ENTITY2))
optional match ((e2Children)<-[e2ChildrenE1Values:VALUE {id:a.id}]-(e1))
optional match ((e2Parent)<-[e2ParentE1Values:VALUE {id:a.id}]-(e1))
optional match ((e2Children)<-[e2ChildrenGlobalValues:VALUE {id:a.id}]-(a))
optional match ((e2Parent)<-[e2ParentGlobalValues:VALUE {id:a.id}]-(a))
RETURN a, e1, entity1GlobalValue, e2Children, e2ChildrenE1Values, e2ParentE1Values, e2ChildrenGlobalValues, e2ParentGlobalValues;
Not sure what is the mistake here?
Is my query effiecent ? There is Unique constraint on id field.
Update:
Rough diagram:
Here I am looking for value which is stored in the relations between Nodes.
Entity2 has children Entity2-1 and Entity2-2, where I have to find the value for these children with other entities - Entity1 and Attribute.
Thanks
Based on the graph provided I understand that you have to get the values for the child nodes which has relationship VALUE. If that's the case find the below query.
MATCH (n:Entity2)-[:CHILD]->(c)
with collect(c)+n as childNodes
UNWIND childNodes as cNode
MATCH (cNode)-[v:VALUE]->(endNode)
RETURN
labels(cNode) as fromNode,
v.value as value,
labels(endNode) as toNode
The result would be
What I have done is assuming the starting Node as parent Node I have collected all the child nodes plus the parentNode and using unwind looping each node collected and checking whether it has VALUE relationship and if so returning the values.
Hope this helps!
If not let me know what's the result you are expecting.
Thanks!

How to query fields with multiple values in Azure Cognitive Search

Working on Azure Cognitive Search with backend as MS SQL table, have some scenarios where need help to define a query.
Sample table structure and data :
Scenarios 1 : Need to define a query which will return data based on category.
I have tied query using search.ismatch but its uses prefix search and matches other categories as well with similar kind of values i.e. "Embedded" and "Embedded Vision"
$filter=Region eq 'AA' and search.ismatch('Embedded*','Category')
https://{AZ_RESOURCE_NAME}.search.windows.net/indexes/{INDEX_NAME}/docs?api-version=2020-06-30-Preview&$count=true&$filter=Region eq 'AA' and search.ismatch('Embedded*','Category')
And it will response with below result, where it include "Embedded" and "Embedded Vision" both categories.
But my expectation is to fetch data only if it match "Embedded" category, as highlighted below
Scenario 2: For the above Scenario 1, Need little enhancement to find records with multiple category
For example if I pass multiple categories (i.e. "Embedded" , "Automation") need below highlighted output
you'll need to use a different analyzer which will break the tokens on every ';' just for the category field rather than 'whitespaces'.
You should first ensure your Category data is populated as a Collection(Edm.String) in the index. See Supported Data Types in the official documentation. Each of your semicolon-separated values should be separate values in the collection, in a property called Category (or similar).
You can then filter by string values in the collection. See rules for filtering string collections. Assuming that your index contains a string collection field called Category, you can filter by categories containing Embedded like this:
Category/any(c: c eq 'Embedded')
You can filter by multiple values like this:
Category/any(c: search.in(c, 'Embedded, Automation'))
Start with clean data in your index using proper types for the data you have. This allows you to implement proper facets and you can utilize the syntax made specifically for this. Trying to work around this with wildcards is a hack that should be avoided.
To solve above mention problem used a below SQL function which will convert category to a json string array supported by Collection(Edm.String) data type in Azure Search.
Sql Function
CREATE FUNCTION dbo.GetCategoryAsArray
(
#ID VARCHAR(20)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE #result NVARCHAR(MAX) = ''
SET #result = REPLACE(
STUFF(
(SELECT
','''+ TRIM(Value) + ''''
FROM dbo.TABLEA p
CROSS APPLY STRING_SPLIT (Category, ';')
WHERE p.ID = #ID
FOR XML PATH('')
),1,1,''),'&','&')
RETURN '[' + #result + ']'
END
GO
View to use function and return desired data
CREATE View dbo.TABLEA_VIEW AS
select
id
,dbo. GetCategoryAsArray(id) as CategoryArr
,type
,region
,Category
from dbo.TABLEA
Defined a new Azure Search Index using above SQL View as data source and during Index column mapping defined CategoryArr column as Collection(Edm.String) data type
Query to use to achieve expected output from Azure Search
$filter=Region eq 'AA' and CategoryArr/any(c: search.in(c, 'Embedded, Automation'))

SuiteScript - Search joining "Term" from "Vendor"

I am doing a search of vendors and want to join in the Term to have the Term's name. The vendor has a field called terms which has the internalid of the Term. Term has a field called name which contains what I'm looking for.
I've tried just about every combination of building the column but I always get an error:
An nlobjSearchColumn contains an invalid column join ID, or is not in proper syntax: name.
Example of how I'm building the column:
search.createColumn({
name: "name",
join: "terms", // or Term, or Terms, none of it works
label: "termname" // or leave this out or Term or Terms or anything else nothing works
}
What is the right way to create a search for vendor that also includes the term's name?
If you'll look at the Records Browser, terms is not listed as a join on the vendor record. Just get terms as a column (name: 'terms') then when you retrieve the result, use getText instead of getValue.
searchResults[i].getText({
name: 'terms'
});

Aggregation with two different conditions

I'v one issue to write aggregation query. I'v 3 doc.I want filter 2 doc with some condition.In which 2 doc having same data with 1 changed value.
I have 3 entries of data in database. English is default lang for my data. In which 2 entries(one with default lang and other with 'Hindi' lang) having same data with some unique id with one diff language parameter and 3rd entry having only data in default lang another uniqueid.
Now I want data in following condition:
1) I have have sent English as a lang parameter Then query will find out the data with english lang
2) If I send Hindi lang as a parameter then from all entries I get 2 entries one entries with hindi lang and one entry with english(default lang) as a result
Query :
certification.find({$and: [{certificate_id: certificate_id}, {$or : [{lang : lang }, {lang : 'English'}]}]});
lang, certificate_id : parameter passed by user
Please help me to write query with mongodb.

MongoDB: Searching for a keyword from a long string with under Array->Object->Object

Input ImageI am trying to extract keywords from a DB with reviews about hotels.
The document is structured in the following way (and there are 10 documents with the same structure):
(1) Document
(2) Object ID
(3) Reviews (Array) - This has about 233 objects under it, so i am expanding object 0
(4) 0 (This is the first object under Reviews)
(4.1)- Review ID (String)
(4.2)- Content (String) - this is where the review comments lie and i need to get to this.
I am very new queries and any kind of programming. I am unable to get to this 'Content' node. Is there anyone who can help me to get to this node and then search a text word from this string, to return this object as a result.

Resources