2013-01-31 15 views
7

Jestem nowicjuszem w wyszukiwaniu elastycznym i paradygmacie innym niż SQL. Podążałem za tutorialem ES, ale jest jedna rzecz, której nie mogę uruchomić.Wyszukiwanie wielopoziomowych zagnieżdżonych pól w wyszukiwaniu elastycznym

W poniższym kodzie (używam PyES do interakcji z ES) tworzę pojedynczy dokument z zagnieżdżonym polem (tematy), który zawiera inne zagnieżdżone pole (koncepcje).

from pyes import * 

conn = ES('127.0.0.1:9200') # Use HTTP 

# Delete and Create a new index. 
conn.indices.delete_index("documents-index") 
conn.create_index("documents-index") 

# Create a single document. 
document = { 
    "docid": 123456789, 
    "title": "This is the doc title.", 
    "description": "This is the doc description.", 
    "datepublished": 2005, 
    "author": ["Joe", "John", "Charles"], 
    "subjects": [{ 
        "subjectname": 'subject1', 
        "subjectid": [210, 311, 1012, 784, 568], 
        "subjectkey": 2, 
        "concepts": [ 
            {"name": "concept1", "score": 75}, 
            {"name": "concept2", "score": 55} 
            ] 
       }, 
       { 
        "subjectname": 'subject2', 
        "subjectid": [111, 300, 141, 457, 748], 
        "subjectkey": 0, 
        "concepts": [ 
            {"name": "concept3", "score": 88}, 
            {"name": "concept4", "score": 55}, 
            {"name": "concept5", "score": 66} 
            ] 
       }], 
    } 


# Define the nested elements. 
mapping1 = { 
      'subjects': { 
       'type': 'nested' 
      } 
     } 
mapping2 = { 
      'concepts': { 
       'type': 'nested' 
      } 
     } 
conn.put_mapping("document", {'properties': mapping1}, ["documents-index"]) 
conn.put_mapping("subjects", {'properties': mapping2}, ["documents-index"]) 


# Insert document in 'documents-index' index. 
conn.index(document, "documents-index", "document", 1) 

# Refresh connection to make queries. 
conn.refresh() 

jestem w stanie do kwerendy przedmiotów zagnieżdżona polu:

query1 = { 
    "nested": { 
     "path": "subjects", 
     "score_mode": "avg", 
     "query": { 
      "bool": { 
       "must": [ 
        { 
         "text": {"subjects.subjectname": "subject1"} 
        }, 
        { 
         "range": {"subjects.subjectkey": {"gt": 1}} 
        } 
       ] 
      } 
     } 
    } 
} 


results = conn.search(query=query1) 
for r in results: 
    print r # as expected, it returns the entire document. 

ale nie mogę dowiedzieć się, jak kwerendę opartą na pojęć zagnieżdżona polowych.

ES documentation oznacza, że ​​

wielopoziomowy zagnieżdżenia jest obsługiwane automatycznie lub wykrywane wyniku wewnętrznego zapytania zagnieżdżonej automatycznie dopasować odpowiednie poziom zagnieżdżenia (nie główny), jeżeli występuje on w zasięgu innego zagnieżdżone pytanie.

Więc Próbowalismy zbudować kwerendę z następującym formacie:

query2 = { 
     "nested": { 
      "path": "concepts", 
      "score_mode": "avg", 
      "query": { 
       "bool": { 
        "must": [ 
         { 
          "text": {"concepts.name": "concept1"} 
         }, 
         { 
          "range": {"concepts.score": {"gt": 0}} 
         } 
        ] 
       } 
      } 
     } 
} 

który zwrócony 0 wyników.

Nie mogę dowiedzieć się, czego brakuje i nie znalazłem żadnego przykładu z zapytaniami opartymi na dwóch poziomach zagnieżdżenia.

Odpowiedz

12

Ok, po wypróbowaniu ton kombinacji, wreszcie dostałem go za pomocą następującego zapytania:

query3 = { 
    "nested": { 
     "path": "subjects", 
     "score_mode": "avg", 
     "query": { 
      "bool": { 
       "must": [ 
        { 
         "text": {"subjects.concepts.name": "concept1"} 
        } 
       ] 
      } 
     } 
    } 
} 

Więc zagnieżdżona ścieżka atrybut (tematy) jest zawsze taka sama, bez względu na poziom zagnieżdżonego atrybutu, aw definicji zapytania użyłem pełnej ścieżki atrybutu (subject.concepts.name).

+0

Ponieważ używam tylko jednego warunku logicznego, bardziej poprawną definicją zapytania byłoby użycie "zapytania": : {"text": {"subjects.concepts.name": "concept1"}} – JCJS

1

Zastrzelono w ciemności, ponieważ nie próbowałem tego osobiście, ale czy wypróbowałeś w pełni kwalifikowaną ścieżkę do koncepcji?

query2 = { 
     "nested": { 
      "path": "subjects.concepts", 
      "score_mode": "avg", 
      "query": { 
       "bool": { 
        "must": [ 
         { 
          "text": {"subjects.concepts.name": "concept1"} 
         }, 
         { 
          "range": {"subjects.concepts.score": {"gt": 0}} 
         } 
        ] 
       } 
      } 
     } 
    } 
+0

Wysłałem odpowiedź bez odświeżania strony i nie widziałem Twojej odpowiedzi. To było prawie to, wartość ścieżki powinna być tylko "podmiotami". – JCJS

0

Mam kilka pytań do odpowiedzi JCJS. dlaczego twoje mapowanie nie powinno się podobać?

mapping = { 
    "subjects": { 
     "type": "nested", 
     "properties": { 
      "concepts": { 
       "type": "nested" 
      } 
     } 
    } 
} 

Próbuję zdefiniować dwa mapowania typów może nie działa, ale być spłaszczania danych; Myślę, że powinniśmy zagnieżdżone właściwości zagnieżdżonych ..

... W końcu, jeśli używamy tego odwzorowania zagnieżdżone zapytania powinny podoba ...

{ 
    "query": { 
     "nested": { 
      "path": "subjects.concepts", 
      "query": { 
       "term": { 
        "name": { 
         "value": "concept1" 
        } 
       } 
      } 
     } 
    } 
} 

Jest niezbędna do korzystania full path dla atrybutu ścieżki ... ale nie dla klucza warunkowego może być ścieżką pełną lub względną.

Powiązane problemy